【发布时间】:2008-11-11 22:29:15
【问题描述】:
我在后台工作线程上运行了一系列耗时的操作。在各个阶段,我通过调用委托来更新(Windows 窗体)进度条。但是,其中一个比较耗时的操作发生在一行代码上。
有没有可能:
a) 在执行该单行代码时更新 UI,或者至少显示一个动画图标,向用户显示工作正在完成。
b) 让用户在执行该单行代码时取消后台工作线程
【问题讨论】:
标签: backgroundworker
我在后台工作线程上运行了一系列耗时的操作。在各个阶段,我通过调用委托来更新(Windows 窗体)进度条。但是,其中一个比较耗时的操作发生在一行代码上。
有没有可能:
a) 在执行该单行代码时更新 UI,或者至少显示一个动画图标,向用户显示工作正在完成。
b) 让用户在执行该单行代码时取消后台工作线程
【问题讨论】:
标签: backgroundworker
很遗憾,可能不会。后台工作线程需要调用 ReportProgress 来更新 UI 线程,并且需要观察 CancellationPending 来知道它是否应该停止。因此,如果您的工作线程在单行中运行沿运行操作,则无法使其工作。
也许,我误解了,所以这里的代码模拟了我的理解:
public void DoWork() {
System.Threading.Thread.Sleep(10000);
// won't execute until the sleep is over
bgWorker.ReportProgress(100);
}
【讨论】:
a) 您可以使用 PictureBox 控件在表单上显示动画 GIF 而不是进度条。您可以在this blog post 中找到有关如何执行此操作的详细信息。
b) BackgroundWorker 类有一个 CancelAsync 方法,该方法将提交取消当前操作的请求。
这将设置 CancellationPending将 BackgroundWorker 的 strong> 属性设置为“True”。然后,在您的 DoWork 事件处理程序中,您必须定期轮询此属性,以便在其值更改时采取适当的操作。
另请注意,要使其正常工作,您必须将 BackgroundWorker 的 WorkerSupportsCancellation 属性设置为“True”。
【讨论】:
您的 ui 代码可以在启动后台工作程序之前显示动画,如果需要取消,您可以终止后台线程。很遗憾,您将无法使用后台工作人员设计。
【讨论】:
您可以在 ReportProgress() 方法中更新 UI(或类属性)
所以,如您所说,如果您的长期操作稳定且无响应,您希望如何计算其进度?这显然是不可能的。
尽可能多地将您的操作与 sn-ps 分开,并在每个 sn-p 之后调用 ReportProgress()。
【讨论】:
您没有误解 - 使用 ReportProgress 或使用委托(就像我一样)可以实现基本相同的目标。
【讨论】: