- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在 MSDN article关于 BackgroundWorker.CancelAsync
方法,有一个警告说:
Be aware that your code in the
DoWork
event handler may finish its work as a cancellation request is being made, and your polling loop may missCancellationPending
being set to true. In this case, theCancelled
flag ofSystem.ComponentModel.RunWorkerCompletedEventArgs
in yourRunWorkerCompleted
event handler will not be set to true, even though a cancellation request was made. This situation is called a race condition and is a common concern in multithreaded programming.
public partial class MainWindow : Window
{
BackgroundWorker bW;
int bWsCount = 0;
public MainWindow()
{
InitializeComponent();
}
private void Window_MouseMove(object sender, MouseEventArgs e)
{
if (bW != null)
bW.CancelAsync();
bW = new BackgroundWorker();
bW.WorkerSupportsCancellation = true;
bW.DoWork += new DoWorkEventHandler(bW_DoWork);
bW.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bW_RunWorkerCompleted);
bW.RunWorkerAsync(0);
bWsCount++;
labelBackgroundWorkersCount.Content = bWsCount;
}
void bW_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
if (e.Cancelled || worker.CancellationPending)
{
bWsCount--;
labelBackgroundWorkersCount.Content = bWsCount;
}
else
worker.RunWorkerAsync(1000);
}
void bW_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
int sleepDuration = Convert.ToInt32(e.Argument);
if (worker.CancellationPending) { e.Cancel = true; return; }
Thread.Sleep(sleepDuration);
if (worker.CancellationPending) { e.Cancel = true; return; }
}
}
最佳答案
没有办法避免它,不是每个线程问题都有解决方案。当你把它们推到极致时,这些事情可以被推理出来。想象一下,您的 UI 线程中的代码在工作线程完成前一纳秒调用 CancelAsync()。就像线程正在执行它的最后一条机器代码指令一样。显然,线程无法检测到这一点。 UI 线程也没有任何可能的方法来查看线程是否在执行最后一条指令。
这不是一个真正的问题,只需在编写 RunWorkerCompleted 事件处理程序时记住它。如果 e.Cancelled 属性为 false,则工作人员无论如何都完成了。如有必要,您可以简单地将它与另一个在调用 CancelAsync() 时设置为 true 的 bool 一起使用。大致:
private bool cancelRequested;
private void CancelButton_Click(object sender, EventArgs e) {
cancelRequested = true;
backgroundWorker1.CancelAsync();
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
if (e.Error != null) throw e.Error;
if (!e.Cancelled && !cancelRequested) {
// Completed entirely normally
//...
}
}
关于.net - 使用 BackgroundWorker.CancelAsync 时如何避免竞争条件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10327595/
我制作了一个小应用程序,其中 Form 是线程化的(使用 BackgroundWorker),并且在表单中我调用了一个函数 QuitApplication 当我想退出时在 Program 类中。 Do
我正在尝试使用 Asp.NET Core 创建一个 Web API,它公开路由以开始和取消大文件的长时间下载。服务器应该能够同时处理多个下载。 下载是使用 WebClient.DownloadFile
我有一个运行单个进程的后台工作程序。我希望能够在处理过程中取消它,但是当我调用 CancelAsync() 方法时,它从未真正取消。我哪里错了? 这是 DoWork() 方法: pri
我正在尝试使用 WorkerClass.bw.CancelAsync() 取消我的后台工作程序.但它根本不起作用。 //编辑!我在这里发布了完整的代码。愿这会有所帮助。 好的,我添加了一些 Msgbo
在 MSDN article关于 BackgroundWorker.CancelAsync方法,有一个警告说: Be aware that your code in the DoWork event
我有一种叫做 Sorter 的表格。上面有“jademy”按钮,可以打开“Progress Window”窗口 private void jademy_Click(object sender, Eve
我想中止该过程但无法这样做,我正在使用后台工作程序和我的处理功能。 public void Init() { bw = new BackgroundWorker(); bw.Worke
我需要确保 BackgroundWoker 在被调用之前不忙,所以我检查 IsBusy 并调用 CancelAsync如果是: if (bgWorker.IsBusy)
这很好用: private WebClient _webClient; private void ButtonStart_Click(object sender, RoutedEventArgs e)
我是一名优秀的程序员,十分优秀!