BackgroundWorker 线程:更新 UI 并中止操作
我在后台工作线程上运行一系列耗时的操作。 在各个阶段,我通过调用委托来更新(Windows 表单)进度条。 然而,其中一个较多的时间操作发生在单行代码上。
是否可以:
a) 在执行单行代码时更新 UI,或者至少显示一个动画图标,向用户显示工作正在完成。
b) 让用户在执行该行代码时取消后台工作线程
I run a series of time consuming operations on a background worker thread. At various stages I update a (windows form) progress bar by invoking a delegate. However, one of the more time operations occurs on a single line of code.
Is it possible to :
a) Update the UI while that single line of code is being executed, or at least display an animated icon that shows the user that work is being done.
b) Let the user cancel the background worker thread while that single line of code is being executed
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
不幸的是,可能不会。 后台工作线程需要调用 ReportProgress 来更新 UI 线程,并且需要观察 CancellationPending 以了解是否应该停止。 因此,如果您的工作线程在单行中运行并行操作,则无法完成此操作。
也许,我误解了,所以这里是模拟我所得到的代码:
Unfortunately, probably not. The background worker thread needs to call ReportProgress to update the UI thread, and it needs to watch the CancellationPending to know whether it should stop or not. So, if your worker thread is running along-running operation in a single line, there's no way to make this work.
Perhaps, I've misunderstood, so here's code that simulates what I'm getting at:
a) 您可以使用 PictureBox 控件在表单上显示动画 GIF,而不是进度条。 您可以在 此博文。
b) BackgroundWorker 类有一个 CancelAsync 方法,该方法将提交取消当前操作的请求。
这将设置 CancellationPending 属性将BackgroundWorker 设置为“True”。 然后,在您的 DoWork 事件处理程序中,您必须定期轮询该属性,以便在其值发生变化时采取适当的操作。
另请注意,要使其正常工作,您必须将BackgroundWorker 的WorkerSupportsCancellation 属性设置为“True”。
a) You could display an animated GIF on your form instead of a progress bar by using a PictureBox control. You can find detailed information on how to do that in this blog post.
b) The BackgroundWorker class has a CancelAsync method that will submit a request to cancel the current operation.
This will set the CancellationPending property of the BackgroundWorker to 'True'. In your DoWork event handler then, you will have to poll this property regularly in order to take the appropariate actions when its value changes.
Also note that for this to work, you will have to set the WorkerSupportsCancellation property of the BackgroundWorker to 'True'.
您的 ui 代码可以在启动后台工作程序之前显示动画,如果需要取消,您可以终止后台线程。 不幸的是,您将无法使用后台工作人员设计。
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.
您可以在ReportProgress()方法中更新UI(或类属性)
因此,如果如您所说,您的长时间操作稳定且无响应,您会如何喜欢计算它的进度吗? 显然这是不可能的。
将您的操作分成尽可能多的片段,并在每个片段后调用ReportProgress()。
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 或使用委托(就像我一样)基本上可以实现相同的目标。
You haven't misunderstood - using ReportProgress or using a delegate (as I do) achieve essentially the same goal.