c# - 当使用 Parallel BeginInvoke 时有效而 Invoke 无效 - c# 4.0

标签 c# winforms invoke begininvoke parallel.for

当我在 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/

相关文章:

c# - 将 dataGridView 中的选定行作为对象检索

c# - 在 Windows 8 Pro 平板电脑中使用 WinAPI 抛出 AccessViolationException

c++ - 为什么 `std::invoke` 不是 constexpr?

c# - 使用反射将委托(delegate)连接到事件?

c# - 为什么在这个例子中(来自msdn),在GetEnumerator方法中,new PeopleEnum返回IEnumerator?

c# - C#中的委托(delegate)和继承

c# - MVVM 获取/设置与 OOP

c# - 从父级在 PictureBox 上画一条线

c# - 盲目地使用 InvokeRequired 不是一种不好的做法吗?

c# - 当我在两个连续的语句中读/写它时,我需要锁定一个 bool 值吗?