2009-02-10 69 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()

相关问题