我在后台工作线程上运行了一系列耗时的操作。在各个阶段,我通过调用委托来更新(Windows 窗体)进度条。但是,更多时间操作之一发生在单行代码上。
是否有可能 :
a) 在执行该单行代码时更新 UI,或者至少显示一个动画图标,向用户显示工作正在完成。
b) 让用户在执行该单行代码时取消后台工作线程
我在后台工作线程上运行了一系列耗时的操作。在各个阶段,我通过调用委托来更新(Windows 窗体)进度条。但是,更多时间操作之一发生在单行代码上。
是否有可能 :
a) 在执行该单行代码时更新 UI,或者至少显示一个动画图标,向用户显示工作正在完成。
b) 让用户在执行该单行代码时取消后台工作线程
不幸的是,可能不是。后台工作线程需要调用 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 而不是进度条。您可以在此博客文章中找到有关如何执行此操作的详细信息。
b) BackgroundWorker类有一个CancelAsync方法,该方法将提交取消当前操作的请求。
这会将 BackgroundWorker 的CancellationPending属性设置为“True”。然后,在您的DoWork事件处理程序中,您必须定期轮询此属性,以便在其值更改时采取适当的操作。
另请注意,要使其正常工作,您必须将 BackgroundWorker 的WorkerSupportsCancellation属性设置为“True”。
Your ui code can display the animation before it starts the background worker, And if need be to cancel, you can terminate the background thread. You will not unfortunately beable to utilize the background worker design.
You can update the UI (or class properties) in ReportProgress() method
So, if , as you state, your long-time operation is solid and unresponsive, how would you like to calculate its progress? It's evidently impossible.
Separate your operation to as much snippets as you can and call ReportProgress() after every snippet.
您没有误解 - 使用 ReportProgress 或使用委托(就像我一样)可以实现基本相同的目标。