【问题标题】:Using BackgroundWorker to update main form UI with FileSystemWatcher?使用 BackgroundWorker 通过 FileSystemWatcher 更新主窗体 UI?
【发布时间】:2020-06-02 12:54:52
【问题描述】:

我在尝试使用 BackgroundWorker 来更新我的主表单 UI 以响应 FileSystemWatcher 事件被触发时有点卡住了。

  1. FileSystemWatcher 检查添加到特定文件夹的图像,触发 OnCreated 处理程序
  2. OnCreated 处理程序调用 RunWorkerAsync(e.FullPath) 将文件名传递给后台工作人员
  3. 后台工作人员 RunWorkerAsync 获取文件路径,并将项目添加到 List(Of Product)
  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. 如果在工作人员完成之前引发另一个文件事件,我如何检查工作人员是否忙?

【问题讨论】:

  • 您明确提出了两个不同的问题,这明显违反了规则。如果您有两个问题,请创建两个问题。除非一个人同时解决两个问题,否则您几乎无法接受两个单独问题的单一答案。请遵守规则。
  • 第二个问题似乎没有任何意义。

标签: vb.net winforms


【解决方案1】:

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

其次,您不要触摸 DoWork 事件处理程序中的 UI 或从中调用的任何方法。这都是在辅助线程上执行的,除了 UI 线程之外,您不能在任何地方修改 UI。您可以在DoWork 事件处理程序中完成所有工作,然后将结果数据分配给e.Result 属性。

然后您处理在 UI 线程上执行的 RunWorkerCompleted 事件,从 e.Result 属性取回该数据,然后更新 UI。我不知道您在那里使用的确切控件,但您应该能够在辅助线程上创建项目,但是您需要将它们添加到 UI 线程上的控件中。

你可以找到我自己的BackgroundWorker例子here

【讨论】:

  • VbForums 错误消息为PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197这表明对论坛所涉及的技术充满信心:)
  • @AndrewMorton,他们有一个用于 vBulletin 的自定义插件,它为代码 sn-ps 提供语法突出显示,每次升级站点软件时总是需要手动注意,并且最新的 vBulletin 更新导致由于有些不兼容。网站管理员一再将问题推到链条上,但网站所有者似乎不愿意解决它。除了帖子中带有highlight 标签的页面显示这些错误并且包含这些标签的帖子尝试提交两次之外,一切似乎仍然运行良好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-02
  • 1970-01-01
  • 2011-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多