如何暂停BackgroundWorker?或类似的问题

8
我使用了 BackgroundWorker 在循环中调用 WebClient.DownloadString 来下载一些网站。我想要提供一个选项,让用户在下载过程中可以取消操作,所以当在循环的过程中发现 CancellationPending 为真时,我就调用 CancelAsync
但是我注意到函数 DownloadString 有时会卡住,因此我决定在 BackgroundWorker 创建的线程中使用 DownloadStringAsync。由于我不想通过调用 DownloadStringAsync 后退出循环和函数来重写整个代码,所以我在调用它后加了一个 while 循环,只检查一个名为 bool Stop 的变量是否为真。我将该变量设为 true,要么当 DownloadStringCompleted 事件处理程序被调用时,要么当用户请求取消操作时。
现在,奇怪的是,在调试版本下它能够正常工作;但是在发布版本下,程序在 while 循环中像主线程一样冻结了。
3个回答

4
听起来你正在使用while循环进行忙等待。你应该使用事件信号,例如WaitHandle。在发布模式下,忙等待循环可能会消耗所有CPU资源,导致冻结的感觉。
在DownloadStringCompleted事件中或者用户取消下载时发出WaitHandle信号。
请查看WaitHandle类的MSDN文档。那里也有一个示例。

在后台工作器中暂停/恢复循环 - Steven Du

0

很好的主题,我在我的后台工作进程中使用了一个双 while 循环

 int icounter = 1;
 while (icounter < SomeListInventory.Count)
            {
                while (pauseWorker == false)
                { 
                    //-----------------------
                    //DO SOME WORK
                        icounter++;
                    //-----------------------
                }
            }

我有一个暂停按钮,当我按下它时,pauseWorker(全局变量或属性)变为true,并仅在第一个while循环中循环,而不增加icounter的值。当我再次将pauseworker=false时,进程继续进行。


0

让你的 while 循环在检查取消时短暂休眠(几毫秒)。这将释放 CPU 运行时间以供其他线程和进程使用。


1
忙等待是一种不好的编程实践。 - Mikael Svenson
我知道并不知道C#/.Net中有类似WaitHandle的东西(总是有新东西要学习 :-)),但有时轮询是唯一的解决方案,然后应该确保进程轮询仅检查一次,然后放弃由操作系统分配给线程/进程的CPU时间(在Linux中是yield()函数)。 - Mark
WaitHandles也可以与超时一起使用,这样就可以避免轮询 :) (我以前也曾经使用过很多忙等待直到我变得更聪明.. 嘿嘿) - Mikael Svenson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接