2013-01-17 21 views
34

你能解釋一下這對我好嗎:如何使用的BeginInvoke C#

someformobj.BeginInvoke((Action)(() => 
{ 
    someformobj.listBox1.SelectedIndex = 0; 
})); 

你能告訴我怎樣才能使用begininvoke到底是什麼? 什麼是Action類型? 爲什麼有空白的括號()? 這是什麼意思=>

+2

在一個帖子中有這麼多不同的問題... - 應該至少有3個單獨的問題 – Prokurors

+0

請看看這篇文章以及http://mark-dot-net.blogspot.com.uy/2014/07 /six-ways-to-initiate-tasks-on-another.html –

回答

57

Action是由.NET框架提供的委託類型。 Action指向一個沒有參數且不返回值的方法。

() =>lambda expression語法。 Lambda表達式不是Delegate。調用需要DelegateAction所以可用於包裹lambda表達式和提供預期TypeInvoke()

Invoke使所述Action創建該控制的窗口句柄的線程上執行。改變線程通常是必要的,以避免Exceptions。例如,如果在沒有首先調用Invoke的情況下需要Invoke時嘗試在RichTextBox上設置Rtf屬性,則會拋出異常。在調用Invoke之前,請檢查Control.InvokeRequired

BeginInvokeInvoke的異步版本。異步意味着線程不會阻塞調用者,而不是阻塞的同步調用。

+0

Thannk u非常多:) –

+0

所以如果我正確理解這個,Action用來保證跨線程安全,所以你可以通過方法調用來通知對象,而不是自己設置值? 此外,該方法將接受任何委託,而不僅僅是一個行動具體,是嗎? –

+4

@KyleBaran - 'Action'與線程安全無關,即'Invoke'。 'Invoke'接受'Delegate'作爲參數。所以任何可以轉換成'Delegate'的東西都可以作爲參數傳遞。 –

9

我猜你的代碼與Windows窗體有關。
如果需要在UI線程中異步執行某些操作,請致電BeginInvoke:在大多數情況下更改控件的屬性。
粗略地說,這是通過將委託傳遞給正在定期執行的某個過程來完成的。 (消息循環處理和類似的東西)

如果調用BeginInvoke類型Delegate類型委託只是異步調用。
Invoke的同步版本。)

如果你想這完全適用於WPF和WinForms,你可以考慮任務並行庫和運行Task與根據context更普遍的代碼。 (TaskScheduler.FromCurrentSynchronizationContext()

並添加一點,已被其他人說: 蘭姆達斯可以被視爲匿名方法或expressions
這就是爲什麼你不能只用var與lambda表達式:編譯器需要一個提示。

UPDATE:

這需要.NET V4.0及更高版本

// This line must be called in UI thread to get correct scheduler 
var scheduler = System.Threading.Tasks.TaskScheduler.FromCurrentSynchronizationContext(); 

// this can be called anywhere 
var task = new System.Threading.Tasks.Task(() => someformobj.listBox1.SelectedIndex = 0); 

// also can be called anywhere. Task will be scheduled for execution. 
// And *IF I'm not mistaken* can be (or even will be executed synchronously) 
// if this call is made from GUI thread. (to be checked) 
task.Start(scheduler); 

如果你開始從其他線程中的任務,需要等待其completition task.Wait()會阻塞調用線程,直到任務結束。

閱讀更多關於任務here

+0

你能舉幾個例子嗎? –

+0

@MohammedNoureldin我添加了一些代碼 –