Winforms Windows窗体UI线程是否异步或顺序处理多个backgroundworkercompleted事件?

Winforms Windows窗体UI线程是否异步或顺序处理多个backgroundworkercompleted事件?,winforms,backgroundworker,.net-2.0,ui-thread,Winforms,Backgroundworker,.net 2.0,Ui Thread,我有一个WindowsFormsApp.NET2.0,它启动了许多Backgroundroker线程,并分别在更新/完成时处理ProgressChanged和Completed事件。然而,我遇到了一个让我猜测的情况 我启动Backgroundworker1BW1,然后启动Backgroundworker2BW2。假设BW1首先完成并触发BackgroundWorkerCompleted事件,UI线程在我的事件处理程序workerCompleted中处理该事件。事件处理程序需要一段时间,因为它调用

我有一个WindowsFormsApp.NET2.0,它启动了许多Backgroundroker线程,并分别在更新/完成时处理ProgressChanged和Completed事件。然而,我遇到了一个让我猜测的情况

我启动Backgroundworker1BW1,然后启动Backgroundworker2BW2。假设BW1首先完成并触发BackgroundWorkerCompleted事件,UI线程在我的事件处理程序workerCompleted中处理该事件。事件处理程序需要一段时间,因为它调用另一个函数

现在,我在EventHandler的开头放置了一个断点,并逐步完成了代码的运行。当我在处理BW1时单步处理eventhandler时,UI线程突然切换到处理BW2

最终,UI线程完成了BW1,但我有一个争用条件,这是由该外部函数中的这种不可预测的行为引起的。线程锁定没有帮助,因为UI线程在第二次重入锁时忽略了锁

现在,如果我更改代码,以便在eventhandler调用该外部函数之前放置Application.DoEvents,它会改进但不会完全修复可预测的行为,或者我应该说,我的预期行为

因此,尽管可能是冗长的,UI线程是否应该在处理下一个事件处理程序之前完成一个事件处理程序?或者我应该期望它是不确定的

void WorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
         // Do some cleanup related things, generate report, etc.
         ...
         // Call some external function to get a value which will increment on next call
         int x = CallExternalFunction();
         // While code is in the above function, UI switches to handling BW2 at the top of this function.  
         // BW2 then calls external function and finishes before BW1 returns
    }
注意,外部函数中没有与线程相关的或Application.DoEvents类型代码。实际上,它只是一个对象队列,每次获取一个对象并递增一个内部计数器

更新:我找到了我的答案。我正在使用我没有编写的代码,并且过分简化了外部函数的工作。我一直跟踪它,直到我发现它最终调用了Application.DoEvents,这会中断当前的eventhandler,并强制UI处理其他事件


我为我的盲目和懒惰道歉。也许这本身就可以帮助以后找到它的人。

Hmm,一个对象队列使用一个锁。用锁阻塞UI线程是非法的,CLR会启动。或者您只是对调试器在线程之间切换的方式感到困惑,第二个断点实际上在BW2的DoWork代码中。对象队列中没有锁。它只是一个带有当前位置计数器的列表。我敢肯定我没有破坏嫁妆。我正在观察VS2008中的线程窗口,当出现这种情况时,只有一个线程出现在主线程中。当BW1被中断时,thread窗口中唯一改变的是threads窗口中的Location列,它现在正确地指向WorkerCompleted函数。检查对象表明它确实是BW2。您必须发布复制代码才能获得帮助,不是这样。