2010-02-24 84 views
4

當我嘗試從自定義面板控件讀取屬性時出現此錯誤。該屬性返回面板中文本框的值。如何讀取從另一個線程返回文本框控件值的屬性?我的房產代碼樣本如下。我不擔心二傳手。當讀取屬性時,跨線程操作無效

以下是eaxct錯誤消息: 跨線程操作無效:從其創建線程以外的線程訪問控制''。

public string Header 
{ 
get 
{ 
    return _HeaderComboBox.Text; 
} 
set 
{ 
    _HeaderComboBox.Text = value; 
} 
} 
+0

看:這可以通過使用Invoke方法來完成 http://stackoverflow.com/questions/2316631/how-to-make-thread-safe-calls-to-windows-forms-控制 – n535 2010-02-24 22:25:22

回答

6

MSDN sample using BeginInvoke

這是我將如何實現基於吸氣片斷您發佈的示例:

public string Header { 
    get { 
     string text = string.Empty; 
     _HeaderComboBox.BeginInvoke(new MethodInvoker(delegate { 
      text = _HeaderComboBox.Text; 
     })); 
     return text; 
    } 

    set { 
     _HeaderComboBox.Text = value; 
    } 
} 

有更優雅的方式,然而,這對你是一個普通的例子。

+1

他沒有說他在哪個平臺上。此鏈接適用於WinForms;對於WPF,請改用Dispatcher.BeginInvoke。 – itowlson 2010-02-24 22:28:22

+1

謝謝。我認爲這解決了我的問題。唯一的問題是它一直返回一個空字符串。正在使用調用而不是BeginInvoke正確的方式來做到這一點? – 2010-02-24 23:18:20

+0

如果它返回一個空字符串,那麼你沒有設置文本屬性。我在一個測試項目中做了這件事,以確保它能夠工作 - 並且它確實返回了文本屬性。 – IAbstract 2010-02-25 00:01:09

3

您需要編組回調到UI線程才能訪問該屬性。

在.NET 2.0之前,您必須調用Control類的Invoke method才能將調用編組爲Text proprety。

在.NET 2.0及之後,如果您的後臺線程有權訪問UI線程的SynchronizationContext,則可以撥打Send method以將回調編組回UI。

請注意,如果你沒有等待調用的結果(如你在這裏做的,因爲你要調用的Text屬性的結果),你可以在控制調用BeginInvokePost和SynchronizationContext分別。

0

你必須將你的跨線程代碼外包給一個單獨的方法,做一個委託,然後Invoke它在你想改變的線程中的一個控件上。你也可以使用閉包而不是委託+方法。

2

您不能在除UI線程A.K.A以外的任何線程上訪問WinForms控件。它是由於交叉線程問題,競爭條件等而創建的。爲了解決這個問題,你必須運行你想在UI線程上運行的任何命令。這裏

public void InvokeExample() 
{ 
    if (InvokeRequired) 
    { 
     // Invoke this method on the UI thread using an anonymous delegate 
     Invoke(new MethodInvoker(() => InvokeExample())); 
     return; 
    } 

    string header = Control.Header; 
}