2011-10-01 135 views
3

我用這樣的代碼:這是異步調用同步方法的正確方法嗎?

handler.Invoke(sender, e); 

但隨着代碼的問題是,它是同步的,它確實做到的就是更新GUI。服務器不需要等待它完成,因此它應該是異步的。

我真的不想使用BeginInvoke和EndInvoke,因爲在這種情況下不需要回調方法。

這是一個合適的選擇嗎?

Task.Factory.StartNew(() => handler.Invoke(sender, e)); 
+0

'handler'是什麼類型? – svick

+0

@svick:'EventHandler ' –

+0

您所想的一切實際上並不奏效。如果你想在UI線程上運行代碼,然後使用Dispatcher.Invoke或Control.BeginInvoke(),無論你選擇的是哪個庫。 –

回答

-1

我不熟悉C#4的Task類,但我知道BeginInvoke在沒有EndInvoke的情況下工作得很好。我有時會這樣寫代碼:

handler.BeginInvoke(sender, e, null, null); 

編輯:我錯了。儘管EndInvoke並不是使代碼在新線程上執行所必需的,但文檔清楚地指出EndInvoke非常重要。

+2

有了這段代碼,'handler'拋出的任何異常都會被忽略。所以如果你想這樣做,你最好知道你在做什麼。 – svick

+0

@Joshua:是的,但是如文檔所述,BeginInvoke調用必須以EndInvoke調用(通常放在回調中)結束。 –

+0

@svick:好點。但是,Task.Factory.StartNew必須具有相同的問題,因爲異常只能在引發它們的線程中捕獲。你必須知道你在做什麼。 –

0

對GUI的調用很特別,因爲它們必須始終從GUI線程完成。用你自己的話說,handler.Invoke(sender, e)「更新GUI」,但它可能(不可能)從GUI線程執行,所以它在當前形式中不能正確執行。

在WinForms中,您需要將您的任務代理包裝到Control.Invoke(或忘記任務並僅使用Control.BeginInvoke)。

如果是WPF,你可以將你的任務委託包裝成Dispatcher.Invoke(或者只是在沒有任務的情況下使用Dispatcher.BeginInvoke)。

+0

我已經在事件處理程序中這樣做了。我想知道如果我也應該異步調用事件處理程序,如果是這樣,如果最初發布的代碼是正確的方式這樣做。 –