- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
更新了答案:等待多个不同任务完成的真正方法需要异步等待而不是后台工作程序。
#我知道有很多关于 backgroundworker 的讨论,但我一直在搜索,但找不到答案。
这是我的代码示例(基本逻辑,实际代码要长得多),我想知道是否有办法解决这个问题:
BackgroundWorker MCIATS1Worker = new BackgroundWorker();
private AutoResetEvent _MCIATS1WorkerResetEvent = new AutoResetEvent(false);
public MainWindow()
{
InitializeComponent();
MCIATS1Worker = new BackgroundWorker();
MCIATS1Worker.DoWork += new DoWorkEventHandler(MCIATS1Worker_DoWork);
MCIATS1Worker.WorkerReportsProgress = true;
MCIATS1Worker.WorkerSupportsCancellation = true;
MCIATS1Worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(MCIATS1_RunWorkerCompleted);
for (int i = 1; i <= 10; i++)
{
//some code
MCIATS1Worker.RunWorkerAsync();
_MCIATS1WorkerResetEvent.WaitOne();
}
}
DoWork 和 runworkercompleted
void MCIATS1Worker_DoWork(object sender, DoWorkEventArgs e)
{
//do something here
}
void MCIATS1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("hello world");
_MCIATS1WorkerResetEvent.Set();
}
由于某些原因,MCIATS1_RunWorkerCompleted 在循环完成之前不会被触发。显然 WaitOne 正在控制循环。
这是我的问题,
为什么 Worker 真正完成工作时,RunWorkerCompleted 不会触发 RunWorkerCompleted?
谢谢。
###更新的解决方案这是正确的做法。
private async void WhateverFunction()
{
await Task.WhenAll(MCIATS1WorkerDoWorkAsync(param),...other tasks);
}
private Task MCIATS1WorkerDoWorkAsync(bkgWorkParameter param)
{
return Task.Run(() =>
{
//Do whatever
});
}
最佳答案
发生这种情况是因为当您使用 BackgroundWorker
时,RunWorkerCompleted
事件被发布到调用 RunWorkerAsync< 的线程的
.SynchronizationContext
/
因为您在 UI 线程上调用了 RunWorkerAsync
,所以在 UI 线程开始处理消息循环中的新消息之前,事件无法运行。但是,您通过 _MCIATS1WorkerResetEvent.WaitOne();
调用阻止了 UI 线程返回消息循环。
所以它归结为 _MCIATS1WorkerResetEvent.Set();
正在等待 MCIATS1_RunWorkerCompleted
触发以停止阻塞,而 MCIATS1_RunWorkerCompleted
正在等待_MCIATS1WorkerResetEvent.Set();
停止阻塞 UI 线程,以便处理消息。
两件事情都在等待对方完成,然后自己完成,这就是典型的死锁。
这个问题不需要 for
循环,无论有没有循环,同样的问题都会发生,事实上,循环永远不会运行它的第二次迭代,因为它会在第一次通过时就陷入了僵局,所以有一个循环根本无关紧要。
关于C# backgroundworker RunworkerCompleted 与异步等待,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43688981/
当我的应用程序中的项目完成时,我正在使用多个外部服务。我必须联系的每项服务都有自己的 BackgroundWorker 来执行其任务。我跟踪有多少 worker 完成了他们的工作以确定是否有任何错误。
后台 worker 有一个非常奇怪的问题。代码太复杂所以会尝试解释问题只是想知道是否有人见过类似的东西。我们让 UI 线程脱离后台线程后台线程在后台打印到 pdf 打印机完成后它就死了,因为线程函数退
在主线程中我有一个Timer。在 Tick 事件中,我运行了一个 BackgroundWorker。我在那里做了一些事情,之后 BackgroundWorker 调用了 RunWorkerComple
我的控制台应用程序使用 System.ComponentModel.BackgroundWorker 进行线程处理: System.ComponentModel.BackgroundWorker ba
我正在使用 BackgroundWorker 线程执行一项长任务(基本上是读取一个大的 xml 文件)。工作人员第一次按预期正常工作,但如果我上传第二个 xml 文件,使用相同的后台工作人员,它有时工
更新了答案:等待多个不同任务完成的真正方法需要异步等待而不是后台工作程序。# 我知道有很多关于 backgroundworker 的讨论,但我一直在搜索,但找不到答案。 这是我的代码示例(基本逻辑,实
在下面的代码中,当 BackgroundWorker 启动时,SynchronizationContext 确实 存在,但是 RunWorkerCompleted 处理程序在与 RunWorkerAs
如果我有一个后台 worker 在它的工作中做一些任务 String val= getVal("Val"); byte[] b = (byte[])e.Argument; b
据我所知,这个事件 promise 在创作者线程中被调用(BackgroundWorker RunWorkerCompleted Event);在大多数情况下,它会按照 promise 行事。但是,有
使用以下代码,永远不会调用我的后台工作人员RunWorkerCompleted,我也不知道为什么。 void startWaitScan() { backgroundWorker1.RunWo
我有一个带有 backgroundWorker 的 WinForm: using System; using System.Collections.Generic; using System.Comp
我的 C# 应用程序有几个后台工作程序。有时,一名后台工作人员会解雇另一名后台工作人员。当第一个后台工作程序完成并触发 RunWorkerCompleted 事件时,该事件将在哪个线程上触发,UI 还
我创建了一个带有进度条的小项目来测试 BackgroundWorker做它的工作。所以进度条从 0 到 100%。但是现在我要做的是触发另一个BackgroundWorker在第一个完成其工作后。第二
在 RunWorkerCompleted 事件中重新抛出异常时,我遇到了 BackgroundWorker 或 .NET 框架的奇怪行为。 后台线程中发生的异常被传递给RunWorkerComplet
我可以从我的调试消息中看到 e.Result 在 DoWorker 方法中一直等于“成功”,但在 RunWorkerCompleted 方法开始时 e.Result 根本不返回任何内容。 这是 Win
这个问题在这里已经有了答案: Disabling .NET progressbar animation when changing value? (5 个答案) 关闭 7 年前。 我正在开发我的第一
我正在使用 VS 2015 winform 后台 worker 来完成一些任务。 我有 DoWork()使用 List myList 的方法,一旦某个过程完成,它就会删除列表中的每个条目。我的目标是让
我正在用 C# 做一些业余爱好项目,这是一种我不太了解的语言,并且偶然发现了以下内容: 假设您有一个使用 BackgroundWorker 实现的异步操作。现在,如果出现异常,将引发事件 RunWor
backgroundWorker 的全部意义在于在完成耗时任务后更新 UI。该组件在我的 WPF 应用程序中像宣传的那样工作。 但是在我的测试中,回调不会在调用线程上调用。 [Test] public
我不是在我的窗口窗体中而是在实现所有处理的类文件 (BusinessLogic) 中创建 backgroundworker。在主窗体中,我首先调用初始化 BGW 的 BL 方法。然后我调用将启动 BG
我是一名优秀的程序员,十分优秀!