2011-09-23 68 views
2

* strong text *我正在測試下面寫的一段TPL代碼。兩個ManagedThreadId顯示不同的數字。因此,我假設,新任務正在非UI線程上運行。爲什麼非UI線程能夠修改WinForm和TPL中的UI控件?

我的問題是該任務如何顯示消息並更改UI控件?我錯過了一些東西。我認爲我需要獲得對UI的SynchronizationContext的引用,並使用它來從其他線程進行UI更改。

//var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext(); 
MessageBox.Show(Thread.CurrentThread.ManagedThreadId.ToString()); 

Task testTask = new Task(() => { 
     MessageBox.Show(
      Thread.CurrentThread.ManagedThreadId.ToString()); 
     lblTest.Text = "Test"; 
    }); 
testTask.Start(); 

增加:

下載VS解決方案here

加2

有人可以測試解決方案,並提到,如果他們得到一個異常或不?

+0

爲什麼駕車通過倒票?對我來說似乎是一個合理的問題。 –

回答

3

這不會起作用除非您使用Control.CheckForIllegalCrossThreadCalls屬性來指示運行時不驗證調用線程是否與創建控件的線程相匹配。 (InvalidOperationException:跨線程操作無效:從其創建的線程以外的線程訪問的控制'lblTest')您的測試代碼在我的全新WinForms項目中確實崩潰。 CheckForIllegalCrossThreadCalls(false)是否可能在您的環境中應用?

Getting exception with your source code

+0

該代碼位於按鈕的點擊處理程序中。我沒有得到任何錯誤。我看到了兩個消息框和標籤的文本更改。這是VS 2010 Windows 7 64位中的Winform應用程序。表格只有按鈕和標籤。您可以下載該解決方案。參見上面的鏈接。 –

+0

@Tony:我在Windows 7 64位上使用VS 2010 SP1,創建了一個空的WinForms項目,添加了一個按鈕和一個標籤,並將您的代碼放在按鈕的點擊處理程序中。你能用一個空的項目重現嗎? –

+0

上面的下載鏈接基於一個空的項目。我在兩臺不同的機器上嘗試過它,它工作。 –