2011-04-01 36 views
22

我試圖從非線程以外的線程上創建它的讀取combobox.Text但我得到的錯誤:如何從線程以外的線程讀取組合框?

An unhandled exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll

Additional information: Cross-thread operation not valid: Control 'levelsComboBox' accessed from a thread other than the thread it was created on.

我用.Invoke之前,但只設置屬性,怎麼能我用它來閱讀combobox.Text?因爲.Invoke返回void,我需要一個字符串。或者還有另一種方法可以在沒有調用的情況下執行它?

+0

我認爲這是對[如何獲得返回值時的BeginInvoke /調用被稱爲重複C#](http://stackoverflow.com/questions/2214002/how-to-get-return-value-when-begininvoke-invoke-is-called-in-c) – 2011-04-01 16:30:49

回答

44

你可以這樣說:

this.Invoke((MethodInvoker)delegate() 
    { 
     text = combobox.Text; 
    }); 
+1

我有2天搜索此解決方案。 thnx – Florjon 2012-03-01 11:46:12

+0

非常棒。它幫助我在C#中實現Observer模式。 – Mythul 2013-06-02 14:10:21

+0

太棒了!上午3點幫助我。抓我的腦袋,記住這句話... – 2014-04-13 00:42:27

2

最簡單的解決方案是使用BackgroundWorker類在另一個線程上執行工作,同時仍能夠更新UI(例如,在報告進度或任務完成時)。

17

您仍然可以使用Invoke並將其讀取到本地變量中。

事情是這樣的:

string text; 

this.Invoke(new MethodInvoker(delegate() { text = combobox.Text; })); 

由於Invoke是同步的,你有保證text變量將包含組合框的文本值返回後。

4

最短的方法是:

string text; 
this.Invoke(() => text = combobox.Text); 
+0

這似乎並不奏效。請參閱鏈接:http://connect.microsoft.com/VisualStudio/feedback/details/395813/system-delegate-is-not-a-delegate-type – Bill 2012-07-21 15:14:43

+0

@YongkeBillYu鏈接要求登錄。我不明白爲什麼它不會工作,但它應該與接受的解決方案一樣。 – 2016-04-14 14:05:25

+0

@Igor有一個警告,雖然:編譯器抱怨的代碼,除非[你把它轉換成動作類型](http://stackoverflow.com/questions/411579/why-must-a-lambda-expression-becast - 當提供的作爲一種-純代表參數)。請編輯代碼。 – 2016-04-14 14:25:30

相關問題