我在尝试使用 BackgroundWorker 更新我的主表单 UI 以响应 FileSystemWatcher 事件被触发时遇到了一些困难。
- FileSystemWatcher 检查是否有图像添加到特定文件夹,并触发 OnCreated 处理程序
- OnCreated 处理程序调用 RunWorkerAsync(e.FullPath) 将文件名传递给后台工作线程
- 后台工作线程 RunWorkerAsync 获取文件路径,并将项目添加到列表(产品列表)
- List(Of Product) 被添加到主 UI 上的 ListBox 控件
我的第一个问题是在后台工作完成后更新主 UI 线程。我在后台工作人员中处理图像,因为从图像生成缩略图需要几秒钟的时间,并且不想锁定 UI。
我遇到的第二个问题是在我的事件第二次触发之后,并且抛出后台工作人员正忙的异常。
Private HoldingTank As New List(Of Product)
Private Sub LoadImages()
Me.ToolStripStatusLabelUpdate.Text = "Images Loading - Please Wait...."
CheckedListBoxView.Items.Clear()
HoldingTank = Me.CreateImageList()
For Each product As Product In HoldingTank
Me.CheckedListBoxView.Items.Add(New ListViewDataItem With {.Image = product.Image, .ImageAlignment = ContentAlignment.MiddleCenter, .Tag = product})
Next
Me.ToolStripStatusLabelUpdate.Text = "Ready"
End Sub
Public Sub WatchFolders()
watcher.Path = PathImport
watcher.Filter = "*.tif"
AddHandler watcher.Created, AddressOf OnCreated
watcher.EnableRaisingEvents = True
End Sub
Sub OnCreated(sender As Object, e As IO.FileSystemEventArgs)
BackgroundWorker1.RunWorkerAsync(e.FullPath)
End Sub
Private Sub BackgroundWorker1_LoadImages(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
HoldingTank.Add(New Product() With {.FileName = path.getFileName(e.argument), .FileExtension = path.GetExtension(e.argument), .FileFullPath = e.argument, .Image = GenerateThumbnail(e.argument)})
'// Function GenerateThumbnail returns an Image object
End Sub
- BackgroundWorker 将项目添加到列表后,如何更新 CheckedListBoxView 控件,而不会收到非法的跨线程调用?
- 如果在工作线程完成之前引发另一个文件事件,我如何检查工作线程是否正忙?
最佳答案
首先,确保您已设置 FileSystemwatcher
的 SynchronizingObject
属性。如果没有,它将在辅助线程上引发其事件,在这种情况下您不希望这样做。您应该将表单分配给该属性。
其次,您不要触摸 DoWork
事件处理程序中的 UI 或从中调用的任何方法。这一切都在辅助线程上执行,除了 UI 线程之外,您无法修改任何其他线程上的 UI。您可以在 DoWork
事件处理程序中完成所有可以完成的工作,然后将结果数据分配给 e.Result
属性。
然后,您可以处理在 UI 线程上执行的 RunWorkerCompleted
事件,从 e.Result
属性取回数据,然后更新 UI。我不确切知道您在那里使用什么控件,但您应该能够在辅助线程上创建项目,但随后需要将它们添加到 UI 线程上的控件中。
您可以找到我自己的 BackgroundWorker
示例 here .
关于vb.net - 使用BackgroundWorker 通过FileSystemWatcher 更新主窗体UI?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62152500/