当我在 AddListBoxItem 函数内部使用 invoke 时,如下所示,软件变得无响应和卡住,但如果我使用 BeginInvoke,它会起作用。为什么会这样?
Visual Studio 2010 , C# 4.0
private void button2_Click(object sender, EventArgs e)
{
var watch = Stopwatch.StartNew();
Parallel.For(2, 20, (i) =>
{
var result = SumRootN(i);
AddListBoxItem("root " + i + " : " + result);
});
AddListBoxItem(watch.ElapsedMilliseconds.ToString());
}
private delegate void AddListBoxItemDelegate(object item);
private void AddListBoxItem(object item)
{
if (this.listBox1.InvokeRequired)
{
this.listBox1.Invoke(new AddListBoxItemDelegate(this.AddListBoxItem), item);
}
else
{
this.listBox1.Items.Add(item);
}
}
最佳答案
您的 UI 线程将等待 Parallel.For
完成,然后再继续。这意味着它在完成之前无法处理任何进一步的 UI 消息。
现在,当工作线程调用 Invoke
时,它们会等到 UI 线程处理完委托(delegate)后再继续。所以他们基本上是在等待 UI 线程释放。
因此,您遇到了死锁 - UI 线程正在等待任务,而任务正在等待 UI 线程...BeginInvoke
起作用,因为任务线程不会 等待在 UI 线程中处理委托(delegate)。
我建议您不要一开始就在 UI 线程中调用 Parallel.For
。您将阻止 UI 直到它完成为止,这不是一个好主意。在后台线程中完成所有操作 - 然后您仍然可以根据需要使用 Invoke
,并且在它进行计算时 UI 仍然会响应。
关于c# - 当使用 Parallel BeginInvoke 时有效而 Invoke 无效 - c# 4.0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7628802/