2009-02-10 45 views

回答

53

Delegate.EndInvoke記錄爲一個你要給這個(即必要的 - 否則泄漏發生) - 從msdn

重要提示

無論您使用哪種技術, 始終調用EndInvoke來完成您的異步c的 所有。

Control.EndInvoke是確定忽略發射後不管的方法 - 從msdn

您可以調用EndInvoke來檢索委託 返回值,如果 neccesary,但這不需要。

但是 - 如果你正在使用Delegate.BeginInvoke和不想要的結果,可以考慮使用ThreadPool.QueueUserWorkItem代替 - 它會讓生活變得更加簡單,並避免IAsyncResult

+0

謝謝Marc,這就是激發這個問題的原因 - 我在通過Richter查看並注意到QueueUserWorkItem,並認爲「一直存在,爲什麼我在其他地方使用BeginInvoke/EndInvoke」。 – endian 2009-02-10 15:21:01

18

EndInvoke不是可選的。

更多信息here

+0

由於盧卡 - 接受的答案。 – endian 2009-02-10 15:25:06

+1

...代表至少; -p – 2009-02-10 15:26:30

+6

從您的鏈接: 「我知道的規則唯一記錄的例外是在Windows窗體中,在那裏您被正式允許調用Control.BeginInvoke而不打擾到調用Control.EndInvoke「。 – Avram 2009-02-10 17:19:28

9

和EndInvoke調用痛不是可選的電話,它是合同的一部分。如果您調用BeginInvoke,則必須調用EndInvoke。

這是爲什麼這是必要的典型例子。從BeginInvoke返回的IAsyncResult很可能已經分配了連接到它的資源。最常見的是一種WaitHandle。由於IAsyncResult不實現IDisposable,所以必須選擇另一個位置來釋放資源。唯一的地方是EndInvoke。

我在下面的博客文章中簡要討論這個問題。因爲它是如果有什麼地方出了問題asyncronous處理拋出異常的地方

http://blogs.msdn.com/jaredpar/archive/2008/01/07/isynchronizeinvoke-now.aspx

4

的EndInvoke是不可選的。

無論如何不應該有任何泄漏,因爲如果IAsyncResult持有一些原生資源,它應該正確實現IDisposable並在GC調用他的終結器時處置這些資源。

2

它只有當你不介意你的程序內存增長很大時纔是可選的。問題在於GC持有線程中的所有引用,因爲您可能想在某個時刻調用EndInvoke。我會馬克的答案,線程池將讓你的生活更輕鬆。但是,您需要注意是否從線程派生線程,因爲線程數量可能會有限。

3

這不是可選的,因爲調用BeginInvoke使用WaitHandle,而WaitHandle反過來利用內核對象來維護一個有多少引用的計數。調用EndInvoke會正確地處理將該計數器遞減到內核對象上的句柄,並且當該計數達到零時,內核對象管理器將銷燬它。

2

對這篇文章的每個回覆都說EndInvoke()不是可選的。但是,我發現以下排名很高的評論是對此SO主題的接受答案:

「請注意,Windows窗體小組已確保您可以使用Control.BeginInvoke方式以」放手而忘記「的方式 - 即無曾經調用EndInvoke,通常情況下,異步調用並不是這樣:通常每個BeginXXX都應該有一個對應的EndXXX調用,通常在回調中。「

What's the difference between Invoke() and BeginInvoke()

相關問題