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