2011-05-02 41 views
1

以下方法將從非UI線程調用。我應該檢查InvokeRequired,是否在方法中調用這些項目?調用請求疑問

a。 this._moduleStatusGrid.Invalidate()
b。 this.Close()

private void CheckIfAllModulesInitComplete() 
     { 
     this._moduleStatusGrid.Invalidate(); 
     if (this._moduleDataList.Count(moduleData => !moduleData.IsInitOver) == 0) 
     { 
      this._footprint.DeActivate(); 
      this.Close(); 
     } 
     } 

回答

3

Control.Invoke和Control.BeginInvoke是安全的,從UI線程和非UI線程調用,因此,如果你已經知道你是在一個非UI線程有沒有危害(IMO)跳過檢查並調用Invoke/BeginInvoke。

例子:

anyControl.Invoke((MethodInvoker)delegate{ 
    // anything to run on UI thread here 
}); 
+0

你能爲你提到的內容添加代碼片段嗎? – Maanu 2011-05-02 14:52:22

+0

@Maanu - 添加示例 – 2011-05-02 16:38:55

+0

這爲我節省了大量的重構問題,這些問題我一直在拉我的頭髮幾天。謝謝! – delliottg 2016-05-20 18:00:19

0

這聽起來像你可能會問既然這個方法在後臺線程中運行以下

  1. 一個,方法InvalidateClose我應該檢查中InvokeRequired屬性?
  2. 鑑於此方法在後臺線程中運行,InvokeRequired屬性將始終返回false因此,我應該避免檢查它嗎?

對於#1答案是否定的。方法CloseInvalidate沒有責任檢查InvokeRequired屬性。合同的一個隱含部分是InvokeRequired屬性在被調用之前是錯誤的。

對於#2,是的,如果它總是在背景線程上調用,我會跳過檢查,直接去Invoke方法。

在這兩種情況下,我會重寫方法如下。

private void CheckIfAllModulesInitComplete() 
{ 
    MethodInvoker del = delegate { 
    this._moduleStatusGrid.Invalidate(); 
    if (this._moduleDataList.Count(moduleData => !moduleData.IsInitOver) == 0) 
    { 
     this._footprint.DeActivate(); 
     this.Close(); 
    } 
    }; 
    this.Invoke(del, null); 
} 
+0

@ JaredPar-謝謝..只是想知道 - 如果this._moduleStatusGrid.Invalidate()或this.Close()直接從回調線程調用會發生什麼? – Maanu 2011-05-02 14:59:50

+0

@Maanu,壞事。偶爾,在一些.Net版本中,應用程序將繼續運行,但沒有明顯的問題。但這並不意味着手術更安全。從BG線程調用這些方法非常危險,並且會導致問題的發生 – JaredPar 2011-05-02 15:02:43