繁体   English   中英

等待后台工作人员完成而不会阻塞UI线程

[英]Waiting for a background worker to finish without blocking UI thread

我有一个应用程序,需要等待后台工作人员完成后才能继续。 后台工作者负责将一些值写入初始化它的USB设备。 后台工作程序的问题在于,我的主程序可以在后台工作程序完成初始化之前尝试访问USB设备。

在后台工作程序工作时,UI线程显示带有动画进度条的“请稍候”。 该进度条反映多远沿后台工作,它仅仅是“旋转”。

我读过一些问题,说不使用后台工作程序,因为我真的不希望它异步运行(这是对的),但是,如果不使用后台工作程序,我的“请稍候”对话框将阻止并且不会t显示动画。 我也读了很多书,告诉我只能使用一个UI线程,然后该线程支持使用后台工作程序。

我还尝试将“请等待”微调器放在单独的线程中,但这会带来复杂性和奇怪的竞争条件,在这种情况下,“请等待”窗口会在打开之前尝试关闭。

解决这个问题的正确方法是什么?

这正是BackgroundWorker设计的目的。 尽管还有其他方法可以完成此操作,但是您所做的就很好。

我读了一些问题,说不使用后台工作者

真的不知道为什么人们建议不要使用它,因为它正是为它设计的。 理想情况下,您想要做的是显示一个带有微调框和取消选项的模式对话框,这样,UI会阻止用户中断USB上的写入过程。

即使在写过程中简单地禁用按钮也足够了。

我认为您正在尝试解决两个单独的问题。

第一个是如何防止主(UI)线程访问未初始化的USB设备。 另一个正在处理“请稍候”微调器对话框。

我的建议是:

  1. 保持BackgroundWworker处理USB设备初始化。
  2. 向您的班级添加一个布尔字段,以在USB设备完成初始化时进行标记,例如

    private volatile bool _usbDeviceInited = false;

  3. 您的后台工作者要做的最后一件事就是将此标志设置为true

  4. 通过属性集中访问USB设备。 如果USB初始化未完成,则getter方法可以检查布尔值字段并返回一个空值(或根据需要引发异常)。
  5. 修改代码以检查是否可以通过提供对USB设备的访问权限的属性返回null(或者处理异常,如果您选择加一,则返回该异常),这表明该USB设备尚未准备好使用。 您可以处理此情况,以警告用户USB设备尚未就绪。

前面的步骤是解决第一个问题的一种方法。 现在,对于微调器。

我建议您使用BackgroundWorkerRunWorkerCompleted事件。 如果您的BackgroundWorker是从主UI线程创建的,则该事件将在主UIThread中触发(这意味着与用户界面元素进行交互是安全的)。 从那里您可以简单地关闭并放置“请稍候”对话框。 您还应该检查AsyncCompletedEventArgs.Error属性,以确保在初始化USB设备时,不会从BackgroundWorker线程引发任何错误情况。

编辑:我刚刚读到您的应用程序可能会运行一个脚本,该脚本立即尝试访问USB设备。 使用我建议的模式,您可以在运行脚本之前“轮询”属性,直到它返回的值不同于null,如下所示:

bool timedOut = false;
DateTime timeout = DateTime.Now.AddSeconds(timeoutSeconds);
while ( MyClass.MyUsbDevice == null ) {
   if( DateTime.Now > timeout ) {
      timedOut = true;
      break;
   }
   Thread.Sleep(0); // Avoid pegging the CPU, yield it to other processes
}

if( !timedOut ) {
   // run the script
} else {
   // Handle timeout
}

祝好运!

将必须在BackgroundWorker完成后执行的部分(脚本)放入BackgroundWorkerRunWorkerCompleted事件处理程序中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM