vb.net - 使用BackgroundWorker 通过FileSystemWatcher 更新主窗体UI?

标签 vb.net winforms

我在尝试使用 BackgroundWorker 更新我的主表单 UI 以响应 FileSystemWatcher 事件被触发时遇到了一些困难。

  1. FileSystemWatcher 检查是否有图像添加到特定文件夹,并触发 OnCreated 处理程序
  2. OnCreated 处理程序调用 RunWorkerAsync(e.FullPath) 将文件名传递给后台工作线程
  3. 后台工作线程 RunWorkerAsync 获取文件路径,并将项目添加到列表(产品列表)
  4. 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
  1. BackgroundWorker 将项目添加到列表后,如何更新 CheckedListBoxView 控件,而不会收到非法的跨线程调用?
  2. 如果在工作线程完成之前引发另一个文件事件,我如何检查工作线程是否正忙?

最佳答案

首先,确保您已设置 FileSystemwatcherSynchronizingObject 属性。如果没有,它将在辅助线程上引发其事件,在这种情况下您不希望这样做。您应该将表单分配给该属性。

其次,您不要触摸 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/

相关文章:

c# - 来自 httpResponse.end() 的缓冲输出?

c# - 如何在 C# 中强制显示工具提示?

.NET Windows 窗体 datagridview - 必须单击组合框列三次才能获得焦点

c# - 正在创建但未写入的基本 txt 文件

c# - 有什么方法可以自动化 Windows 窗体测试吗?

c# - 如何将数据集绑定(bind)到具有显示和值成员的下拉列表/组合框

ios - DateTime.FromOADate 等价于 swift

vb.net - 切换按钮控制

.net - 在 Microsoft WebBrowser/Windows 窗体 Web 浏览器上显示文件

vb.net - 使用 Visual Studio 代码,编码 vb.net,如何启动我的程序然后进入 Debug模式?