【发布时间】:2014-02-20 15:41:57
【问题描述】:
我正在开发一个启动多个后台工作人员的 WinForms 应用程序。当一个后台工作人员完成时,如果结果失败,它将通过ShowDialog(this)方法显示一个对话框。问题是当多个后台工作人员结果失败时,它会同时显示多个对话框。我不认为这是可能的,但显然是。我正在阅读有关消息循环的一些内容,似乎即使打开了一个对话框,消息循环仍在处理消息,这意味着即使对话框已经打开,也会调用 runworkercompleted。我虽然可以在对话框上使用“锁(myObject)”,但它似乎没有,我猜是因为每次都是同一个线程调用锁。
那么解决此问题的适当方法是什么?我很想只使用这样的标志和循环:
public bool dialogOpen = false;
public bool cancelMessages = false;
public void x_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
while (dialogOpen) {}
if (cancelMessages) return;
dialogOpen = true;
MyDialog dlg = new MyDialog("Something went wrong.");
if (dlg.ShowDialog(this) == DialogResult.Cancel) cancelMessages = true;
dialogOpen = false;
}
这还能用吗?这会导致其他不好的事情发生吗? (这会阻塞消息循环吗?)
【问题讨论】:
-
我刚刚尝试了循环,它阻止了一切。 (对话框不起作用。)我可能必须建立一个消息队列。
-
为什么不只跟踪已完成的后台线程数量与规定的数量,然后当计数降至 0 时,如果有任何失败,您才会显示消息框
-
是的,这很有可能。消息框不会阻止 Windows 消息的正常流动。它只是禁用应用程序中的其余窗口,阻止用户生成输入消息。不使用消息框但更类似于显示消息列表的窗口可能是合适的。这也可以防止用户在愉快地点击离开时意外关闭框。
-
我想我不明白它是如何工作的。如果发送到 RunWorkerCompleted 的消息发生在主 UI 线程上,那么为什么根据 Sinatr 的答案存在竞争条件。我试过实施布尔检查。如果所有内容都在同一个线程上处理,则不应该存在竞争条件...此处不能选择消息框。
标签: c# winforms backgroundworker