2014-10-06 72 views
0

我試圖並行化我的代碼以使其運行速度更快。到目前爲止,這一直都令人頭痛,沒有結果。Control.Invoke方法不返回

我想在同一時間更新幾個DataGridViews:

Parallel.Invoke(
     () => updateDgv1(), 
     () => updateDgv2(), 
     () => updateDgv3() 
    ); 

我已經使用到處推薦網(喜歡這裏http://msdn.microsoft.com/en-us/library/ms171728(v=vs.85).aspx)上容易(但可能不是最優)的方式審理。

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; 
     } 
    } 

主線程卡在「Parallel.Invoke(...)」調用中,等待其他線程完成。

通過 「Parallel.Invoke(...)」 創建的線程會卡在這一點上:

  • mscorlib.dll中System.Threading.WaitHandle.InternalWaitOne(System.Runtime.InteropServices.SafeHandle waitableSafeHandle,長millisecondsTimeout,布爾hasThreadAffinity, 布爾exitContext)
  • mscorlib.dll中!System.Threading.WaitHandle.WaitOne(INT millisecondsTimeout,布爾 exitContext)
  • System.Windows.Forms.dll的!System.Windows。形式.Control.WaitForWaitHandle(System.Threading.WaitHandle WaitHandle的)
  • System.Windows.Forms.dll中!System.Windows.Forms.Control.MarshaledInvoke(System.Windows.Forms.Control的 呼叫者,System.Delegate方法,對象[]指定參數時,布爾同步)
  • System.Windows.Forms.dll中!System.Windows.Forms.Control.Invoke(System.Delegate 方法,對象[]參數)

爲什麼他們卡住了嗎?

回答

4

我假設你從UI線程調用Parallel.Invoke。如果是這樣,那就是問題所在。

Parallel.Invoke阻塞,直到所有的調用完成...這意味着你阻止了UI線程。您開始的任務不能完成,因爲Control.Invoke會阻塞,直到UI線程上的調用完成 - 所以您的子任務正在等待UI線程變爲可用以更新UI,但您的UI線程是等待所有的子任務完成。

可以只需使用BeginInvoke代替Invoke解決這個問題(你可能想這樣做,反正),但它本質上是一個壞主意在UI線程使用Parallel.Invoke,正是因爲它的塊。

+0

會System.Threading.Tasks.Task.Run(Action)的工作,還是我會遇到同樣的問題? – 2014-10-06 14:28:37

+0

@PierreGardin yes只要您不在UI線程中等待它,Task.Run(Action)就會工作。 – Letseatlunch 2014-10-06 14:38:28

+0

@PierreGardin:可以,因爲調用Task.Run不會阻塞等待任務完成。 – 2014-10-06 14:53:02