C# 调用方法不返回

C# 调用方法不返回,c#,.net-4.0,C#,.net 4.0,我正在尝试并行化我的代码,使其运行得更快。到目前为止,这一切都令人头痛,没有结果 我想同时更新几个DataGridView: Parallel.Invoke( () => updateDgv1(), () => updateDgv2(), () => updateDgv3() ); 我尝试过使用网络上推荐的简单(但可能不是最佳)方式(如这里) 主线程被困在“Parallel.Invoke(…)”调用中,等待其他线

我正在尝试并行化我的代码,使其运行得更快。到目前为止,这一切都令人头痛,没有结果

我想同时更新几个DataGridView:

    Parallel.Invoke(
        () => updateDgv1(),
        () => updateDgv2(),
        () => updateDgv3()
    );
我尝试过使用网络上推荐的简单(但可能不是最佳)方式(如这里)

主线程被困在“Parallel.Invoke(…)”调用中,等待其他线程完成

由“Parallel.Invoke(…)”创建的线程此时卡住:

  • mscorlib.dll!System.Threading.WaitHandle.InternalWaitOne(System.Runtime.InteropServices.SafeHandle waitableSafeHandle,长毫秒计时,布尔有线程亲和力, bool exitContext)
  • mscorlib.dll!System.Threading.WaitHandle.WaitOne(int 毫秒刺激,布尔 exitContext)
  • System.Windows.Forms.dll!System.Windows.Forms.Control.WaitForWaitHandle(System.Threading.WaitHandle 等待手柄)
  • System.Windows.Forms.dll!System.Windows.Forms.Control.MarshaledInvoke(System.Windows.Forms.Control 调用方,System.Delegate方法,对象[]args,bool同步)
  • System.Windows.Forms.dll!System.Windows.Forms.Control.Invoke(System.Delegate 方法,对象[]args)

为什么它们被卡住了?

我假设您正在调用
并行。从UI线程调用
。如果是这样,那就是问题所在

并行。调用
块,直到所有调用完成。。。这意味着您正在阻止UI线程。您正在启动的任务无法完成,因为
Control.Invoke
会阻塞,直到对UI线程的调用完成-因此您的子任务正在等待UI线程变为可用以更新UI,但您的UI线程正在等待所有子任务完成


您可以通过使用
BeginInvoke
而不是
Invoke
(您可能无论如何都想这么做)来解决这个问题,但在UI线程中使用
Parallel.Invoke
从根本上说是个坏主意,因为它会阻塞。

我假设您正在从UI线程调用
Parallel.Invoke
。如果是这样,那就是问题所在

并行。调用
块,直到所有调用完成。。。这意味着您正在阻止UI线程。您正在启动的任务无法完成,因为
Control.Invoke
会阻塞,直到对UI线程的调用完成-因此您的子任务正在等待UI线程变为可用以更新UI,但您的UI线程正在等待所有子任务完成


您可以通过使用
BeginInvoke
而不是
Invoke
(您可能无论如何都想这么做)来解决这个问题,但在UI线程中使用
Parallel.Invoke
从根本上说是个坏主意,因为它会阻塞。

会使System.Threading.Tasks.Task.Run(Action)工作,或者我会遇到同样的问题吗?@PierreGardin yes Task.run(操作)可以工作,只要你不在UI线程中等待它。@PierreGardin:yes,那可以工作-因为调用
Task.run
不会阻止等待任务完成。System.Threading.Tasks.Task.run(操作)可以工作吗,或者我会遇到同样的问题吗?@PierreGardin yes Task.run(操作)可以工作,只要你不在UI线程中等待它。@PierreGardin:yes,那可以工作-因为调用
Task.run
不会阻止等待任务完成。
private void updateDgv1() {
    /* some stuff */

    assignValue(this.dgv1, colPos, rowPos, value); /* in a loop */
    }

    delegate void AssigneValueCallback(DataGridView dgv, int columnPos, int rowPos, string valeur);

    public void assignValue(DataGridView dgv, Form form, int columnPos, int rowPos, string value)
    {
        if (dgv.InvokeRequired)
        {
            AssigneValueCallbackd = new AssigneValueCallback(assignValue);
            dgv.Invoke(d, new object[] { dgv, columnPos, rowPos, value });
        }
        else
        {
            dgv[columnPos, rowPos].Value = value;
        }
    }