【发布时间】:2014-10-12 01:33:52
【问题描述】:
我知道如何使用 BackgroundWorker(WinForms 设计器中的 gui 对象),并手动实例化将自定义事件提升到 UI 的线程,但是,我在弄清楚如何使用 ThreadPool 对象(最简单的形式)时遇到了一些麻烦处理将事件提升到表单以进行“安全” UI 操作。
示例如下:
Form1.vb
Public Class Form1
WithEvents t As Tools = New Tools
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
t.Unzip("file 1", "foo")
t.Unzip("file 2", "foo")
t.Unzip("file 3", "foo")
t.Unzip("file 4", "foo")
t.Unzip("file 5", "foo")
t.Unzip("file 6", "foo")
t.Unzip("file 7", "foo")
t.Unzip("file 8", "foo")
t.Unzip("file 9", "foo")
End Sub
Private Sub t_UnzipComplete(ZipInfo As Tools.ZipInfo) Handles t.UnzipComplete
TextBox1.Text = TextBox1.Text & ZipInfo.ZipFile & vbCr
End Sub
End Class
(为演示添加一个多行文本框和一个按钮到这个表单)
工具.vb
Imports System
Imports System.Threading
Imports System.IO.Compression
Public Class Tools
#Region "Zip"
Private _zip As System.IO.Compression.ZipFile
Public Shared Event UnzipComplete(ByVal ZipInfo As ZipInfo)
Public Shared Event ZipComplete(ByVal ZipInfo As ZipInfo)
Public Class ZipInfo
Public Property ZipFile As String
Public Property Path As String
End Class
Public Sub Unzip(ByVal ZipFile As String, ByVal Destination As String)
Dim _ZipInfo As New Tools.ZipInfo
_ZipInfo.ZipFile = ZipFile
_ZipInfo.Path = Destination
ThreadPool.QueueUserWorkItem(AddressOf ThreadUnzip, _ZipInfo)
End Sub
Public Sub Zip(ByVal Folder As String, ByVal ZipFile As String)
Dim _ZipInfo As New Tools.ZipInfo
_ZipInfo.ZipFile = ZipFile
_ZipInfo.Path = Folder
ThreadPool.QueueUserWorkItem(AddressOf ThreadUnzip, _ZipInfo)
End Sub
Shared Sub ThreadUnzip(ZipInfo As Object)
RaiseEvent UnzipComplete(ZipInfo)
End Sub
Shared Sub ThreadZip(ZipInfo As Object)
RaiseEvent ZipComplete(ZipInfo)
End Sub
#End Region
End Class
这段代码应该做什么,如下:
- 在 Button1_Click 上,向线程池添加 9 个项目
- 在每个线程完成时(顺序无关),引发提升到 Form1 的事件
Form1 上引发的事件应该是 UI 安全的,因此我可以使用传递给文本框中的 ZipCompleted / UnzipCompleted 事件的信息。这应该是通用的,这意味着引发事件的函数应该是可重用的,并且不会直接调用表单。 (又名,我不希望 Tools.vb 中的“自定义”子或函数调用 Form1.vb 上的特定元素。通过将类添加到我的项目然后在下输入任何“自定义”表单代码,这应该是通用且可重用的引发的事件(例如,当 Button1_Click 被引发时,即使它是线程化的,其他表单交互也不属于 Button1 对象/类的一部分——它们由编码器写入用户单击时引发的事件。
【问题讨论】:
标签: vb.net winforms thread-safety threadpool