每个BeginInvoke必须跟一个EndInvoke吗?

时间:2022-08-27 21:20:31

This page in the MS documentation, covering asynchrony in Windows Forms applications, states:

MS文档中的此页面,包括Windows窗体应用程序中的异步,指出:

You can call EndInvoke to retrieve the return value from the delegate, if neccesary, but this is not required. (emphasis added)

如果需要,可以调用EndInvoke从委托中检索返回值,但这不是必需的。 (重点补充)

This page covering the general case of asynchronous delegates, states something different:

这个页面涵盖了异步委托的一般情况,说明了一些不同的东西:

No matter which technique you use, always call EndInvoke to complete your asynchronous call.

无论使用哪种技术,始终调用EndInvoke来完成异步调用。

These two seem to be in direct conflict.

这两者似乎存在直接冲突。

Which is true? Can someone explain?

这是真的吗?谁能解释一下?

see also, a post by Phil Haack.

另见Phil Haack的帖子。

Related: Is EndInvoke optional, sort-of optional, definitely not optional?

相关:EndInvoke是可选的,sort-of optional,绝对不是可选的?

3 个解决方案

#1


22  

Unless the documentation for an interface explicitly says otherwise you must call EndInvoke for every place you call BeginInvoke. The primary reason is that EndInvoke is the only time where the owner can safely free certain resources that may be allocated for the BeginInvoke call (such as a WaitHandle).

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

But there are exceptions to this rule. APIs such as Control.BeginInvoke do not require an EndInvoke but it's explicit in the documentation.

但这条规则有例外。诸如Control.BeginInvoke之类的API不需要EndInvoke,但它在文档中是明确的。

#2


13  

Both are true - they're different calls.

两者都是真的 - 他们是不同的电话。

In general you should always call EndInvoke to ensure that any resources acquired by the asynchronous call are released.

通常,您应始终调用EndInvoke以确保释放异步调用获取的任何资源。

However, the Windows Forms team has guaranteed that you don't need to do this for Control.Invoke. You may well need to do it for other implementations of ISynchronizeInvoke though.

但是,Windows窗体团队保证您不需要为Control.Invoke执行此操作。您可能需要为ISynchronizeInvoke的其他实现执行此操作。

#3


1  

I've used the fire-and-forget method with delegates before where the results were "useful if available, but not required". Just remember that you have no completion guarantees with that method. In particular, here's one place that I use it:

我已经在代表之前使用了“即发即弃”方法,其结果是“如果可用,但不是必需的”。请记住,您没有使用该方法的完成保证。特别是,我在这里使用它的一个地方:

  • Start a delegate to check for application updates
  • 启动委托以检查应用程序更新
  • Delegate begins a web request with a timeout
  • 委托以超时开始Web请求
  • If an error/timeout occurs, or if the application is up-to-date, the method simply returns
  • 如果发生错误/超时,或者应用程序是最新的,则该方法只返回
  • If the application is out of date, I place a non-focus-stealing systray message stating so (no systray icon unless the update is available)
  • 如果应用程序已过期,我会发出一个非焦点窃取系统消息,表明这样做(除非更新可用,否则没有系统托盘图标)

Either way, the application continues uninterrupted.

无论哪种方式,应用程序继续不间断。

#1


22  

Unless the documentation for an interface explicitly says otherwise you must call EndInvoke for every place you call BeginInvoke. The primary reason is that EndInvoke is the only time where the owner can safely free certain resources that may be allocated for the BeginInvoke call (such as a WaitHandle).

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

But there are exceptions to this rule. APIs such as Control.BeginInvoke do not require an EndInvoke but it's explicit in the documentation.

但这条规则有例外。诸如Control.BeginInvoke之类的API不需要EndInvoke,但它在文档中是明确的。

#2


13  

Both are true - they're different calls.

两者都是真的 - 他们是不同的电话。

In general you should always call EndInvoke to ensure that any resources acquired by the asynchronous call are released.

通常,您应始终调用EndInvoke以确保释放异步调用获取的任何资源。

However, the Windows Forms team has guaranteed that you don't need to do this for Control.Invoke. You may well need to do it for other implementations of ISynchronizeInvoke though.

但是,Windows窗体团队保证您不需要为Control.Invoke执行此操作。您可能需要为ISynchronizeInvoke的其他实现执行此操作。

#3


1  

I've used the fire-and-forget method with delegates before where the results were "useful if available, but not required". Just remember that you have no completion guarantees with that method. In particular, here's one place that I use it:

我已经在代表之前使用了“即发即弃”方法,其结果是“如果可用,但不是必需的”。请记住,您没有使用该方法的完成保证。特别是,我在这里使用它的一个地方:

  • Start a delegate to check for application updates
  • 启动委托以检查应用程序更新
  • Delegate begins a web request with a timeout
  • 委托以超时开始Web请求
  • If an error/timeout occurs, or if the application is up-to-date, the method simply returns
  • 如果发生错误/超时,或者应用程序是最新的,则该方法只返回
  • If the application is out of date, I place a non-focus-stealing systray message stating so (no systray icon unless the update is available)
  • 如果应用程序已过期,我会发出一个非焦点窃取系统消息,表明这样做(除非更新可用,否则没有系统托盘图标)

Either way, the application continues uninterrupted.

无论哪种方式,应用程序继续不间断。