在 Visual Basic .NET 中实现后台进程(一)

2016-01-29 13:47 3 1 收藏

在 Visual Basic .NET 中实现后台进程(一),在 Visual Basic .NET 中实现后台进程(一)

【 tulaoshi.com - ASP.NET 】

摘要:Rocky Lhotka 建议并实现了一个结构化架构示例,该架构可用于充当辅助线程和 UI 线程之间的媒介,从而简化编写多线程辅助代码和 UI 以对其进行控制的过程。该架构包括可下载的代码示例,可以根据您的应用需要进行调整。

使用多线程,可以使应用程序同时执行多项任务。使用多线程,可以让一个线程运行用户界面,让另一个线程进行复杂运算或在后台操作。由于 Microsoft® Visual Basic® .NET 支持多线程,因此我们很容易获得此功能。

但多线程也有其不足之处。当应用程序使用多个线程时,我们总会遇到这样的问题:多个线程同时尝试与相同的数据或资源进行交互。出现这种情况时,问题就会变得非常复杂并且难以调试。

更糟糕的是,多线程代码通常在最初开发期间似乎运行正常,但在生产过程中则会因为出现意外的情况(多个线程同时与相同的数据或资源进行交互)而导致失败。这样就增大了多线程编程的危险性!

由于设计和调试多线程应用程序非常困难,因此 Microsoft 在 COM 中创建了“单线程单元”(STA) 概念。Visual Basic 6 代码始终在 STA 中运行,因而代码只需考虑单线程即可。这样即可彻底避免共享数据或资源所带来的问题,但是同时也意味着,我们必须采取严格的措施才能利用多线程的优势。

.NET 中不会出现 STA 中的这种常见问题。所有 .NET 代码都在允许多线程操作的 AppDomain 中运行。这意味着 Visual Basic .NET 代码也在 AppDomain 中运行,因此可以使用多线程操作。显然,任何时候进行此操作都必须小心编写代码,以避免线程之间的冲突。

要避免线程之间发生冲突,最简单的方法就是确保多个线程永远不会与相同的数据或资源进行交互。尽管不太可能,但是对于任何多线程应用程序来说,应该在设计时尽量避免使用或尽量少使用共享数据或共享资源。

这样不仅能简化编码和调试过程,还能提高性能。要解决线程之间的冲突,必须使用能够在某个线程完成操作之前阻止或暂停其他线程的同步技术。阻止线程也就是使线程处于空闲状态,不进行任何操作,因此会降低性能。

取消按钮和状态显示

在应用程序中使用多线程的原因有多种,但最常见的原因是我们一方面需要执行一个长时间运行的任务,另一方面又希望某些或所有用户界面对用户来说始终处于响应状态。

至少我们应该使 Cancel(取消)按钮始终保持响应状态,使用户能够通过它告诉系统,他们希望终止长时间运行的任务。

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com)

在 Visual Basic 6 中,我们尝试使用 DoEvents、计时器控件和许多其他方法进行该操作。Visual Basic .NET 中的操作则简单得多,因为我们可以使用多线程。而且,只要我们小心谨慎,就可以完成此操作且不会使代码或调试复杂化。

要在多线程环境中成功实现 Cancel(取消)按钮,关键是要记住 Cancel(按钮)的作用只是“请求”取消任务。由后台任务决定何时停止。

如果我们实现一个能够直接停止后台进程的 Cancel(取消)按钮,则可能会在执行某些敏感性操作的过程中将其停止,或者在后台进程关闭重要资源(例如,文件处理程序或数据库连接)之前将其停止。而这有可能导致严重后果,引起死机、应用程序行为不稳定或应用程序完全崩溃。

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com)

因此,Cancel(取消)按钮的作用应该只是请求停止后台任务。后台任务可以检查某一时间点上是否存在取消操作的请求。如果检测到取消操作的请求,后台线程则可以释放所有资源,停止所有重要操作并正常终止。

虽然请求取消操作非常重要,但是我们更希望能够通过 UI 为用户显示后台进程的状态信息。状态信息可以是文本格式的消息,也可以是完成任务的百分比,或者同时显示两种消息。

要在 Visual Basic .NET 中实现 Cancel(取消)按钮或状态显示,我们所面对的最复杂的问题在于 Windows 窗体库不是对于线程并不安全。这意味着只有创建窗体的线程可以与该窗体或其控件进行交互。其他线程均不能安全地与该窗体或其控件进行交互。

但是,我们却无法避免编写多线程与给定窗体进行交互的代码。因此,运行时可能会产生不可预知的后果,甚至可能会导致应用程序崩溃。

这要求我们在编码时必须小心谨慎,还要确保只有我们的 UI 线程与 UI 进行交互。为此,我们可以建立一个简单的架构,管理后台辅助线程和 UI 线程之间的交互。如果能够实现,则可以使 UI 代码和长时间运行的任务的代码都相对清楚地了解到我们正在使用多线程。

线程和对象

如果要创建一个后台进程并使其可以使用它自己的数据在它自己的线程上运行,最简单的方法是创建专门用于该后台进程的对象。虽然不一定能实现,但它是一个积极的目标,因为它能够大大简化多线程应用程序的创建过程。

如果后台线程在其自身的对象中运行,则后台线程可以使用该对象的实例变量(在类中声明的变量),而无须担心这些变量会被其他线程使用。例如,请考虑下面的类:

Public Class Worker  Private mInner As Integer
                        

来源:https://www.tulaoshi.com/n/20160129/1491518.html

延伸阅读
标签: vb
升级 向导 无需特别处理。 Clipboard Visual Basic 6.0 Clipboard 对象提供了对系统剪贴板的访问。 Visual Basic.NET Clipboard 类提供了在系统剪贴板上放置数据和从其上检索数据的方法。新的 Clipboard 类提供了更多功能,并且支持的剪贴板格式比 Visual Basic 6.0 Clipboard 对象更多。对象模块经过了重新构建以...
标签: vb
扩展标记语言XML是一种简单的数据存储语言,使用一系列简单的标记描述数据,而这些标记可以用方便的方式建立,虽然XML占用的空间比二进制数据要占用更多的空间,但XML极其简单易于掌握和使用。 XML与Access,Oracle和SQL Server等数据库不同,数据库提供了更强有力的数据存储和分析能力,例如:数据索引、排序、查找、相关一致性等,...
标签: vb
从 Visual Basic 6.0 到 Visual Basic.NET 的转换(1) Microsoft Visual Basic.NET 是 Microsoft Visual Basic? 的后续版本,它是基于 .NET 框架重新设计的,您可以用它来轻松地创建用于 Microsoft Windows? 操作系统和 Web 的下一代应用程序。使用 Visual Basic.NET,可视化开发 Web 应用程序、Web 服务、Windows 应用程序和服务器端组件...
标签: vb
升级 向导 将 Currency 数据类型转换为 Decimal,因此以下代码: Dim x As Currency 升级后将变为: Dim x As Decimal Date Visual Basic 6.0 Date 变量在内部以 Double 格式存储,能够作为 Double 类型的变量操作。 Date 变量存储为 IEEE 64 位浮点数,表示从 100 年 1 月 1 日到 9999 年 12 月 31 日的日期和从 0:...
标签: vb
升级 向导 过程的 ParamArray 参数标记有升级警告。例如,以下代码: Function MyFunction(ParamArray p() As Variant) ... End Function 升级后将变为: UPGRADE_WARNING: ParamArray p was changed from ByRef to ByVal Function MyFunction(ByVal ParamArray p() As Object) ... End Function 声明中的...

经验教程

104

收藏

63
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部