2011-05-02 42 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