2009-08-13 61 views
25

This page in the MS documentation,覆盖异步在Windows窗体应用程序,规定:每个BeginInvoke都必须跟一个EndInvoke吗?

您可以调用EndInvoke如果neccesary从委托检索的返回值,但这不是必需的。(强调)

This page covering the general case of asynchronous delegates,规定不同的东西:

不管你使用哪种技术,总是调用EndInvoke来完成你的异步调用。

这两个似乎是直接冲突。

这是真的吗?有人可以解释吗?

另请参阅a post by Phil Haack

相关:Is EndInvoke optional, sort-of optional, definitely not optional?

回答

22

除非接口的文档明确说明,否则您必须为每个调用BeginInvoke的地方调用EndInvoke。主要原因是EndInvoke是所有者可以安全释放可能为BeginInvoke调用分配的某些资源(例如WaitHandle)的唯一时间。

但是这个规则也有例外。 API(如Control.BeginInvoke)不需要EndInvoke,但它在文档中是明确的。

13

两者都是真实的 - 他们是不同的呼叫。

一般来说您应该始终调用EndInvoke以确保释放由异步调用获取的任何资源。

但是,Windows窗体小组已确保您不需要为Control.Invoke执行此操作。虽然你可能需要为ISynchronizeInvoke的其他实现做。

+0

我同意你的大部分答案,除了评论他们是“不同的电话”。他们似乎并不是完全不同的电话。他们是不是都在讨论异端代表的EndInvoke?只是控制代理上的EndInvoke是一个特例。 – Cheeso 2009-08-13 22:37:06

+3

@Cheeso:否 - Control.BeginInvoke根本不是*委托上的调用*。它*需要*代表。 – 2009-08-13 22:41:40

1

在结果“有用(如果可用,但不是必需的)”之前,我已经对代表使用了“忘却”(fire-and-forget)方法。请记住,您没有完成该方法的保证。尤其是,这里有一个地方,我用它:

  • 开始委托来检查应用程序更新如果发生错误/超时
  • 代表一开始就超时
  • web请求,或者如果应用程序为跟上时代的,该方法只返回
  • 如果应用程序是过时的,我把非焦点窃取系统托盘消息,说明这样(系统托盘图标,除非更新可用)

无论哪种方式,第四e应用程序不会中断。

相关问题