【问题标题】:Must every BeginInvoke be followed by an EndInvoke?每个 BeginInvoke 都必须跟 EndInvoke 吗?
【发布时间】:2009-08-13 20:07:20
【问题描述】:

This page in the MS documentation,涵盖 Windows 窗体应用程序中的异步,声明:

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

This page covering the general case of asynchronous delegates,声明不同:

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

这两者似乎直接冲突。

哪个是真的?谁能解释一下?

另请参阅,a post by Phil Haack

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

【问题讨论】:

    标签: .net multithreading begininvoke


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      两者都是正确的 - 它们是不同的调用。

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

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

      【讨论】:

      • 我同意你的大部分回答,除了他们是“不同的电话”的评论。他们似乎根本不是不同的电话。他们不是都在讨论异步代表的 EndInvoke 吗?只是控制委托上的 EndInvoke 是一个特例。
      • @Cheeso:不——Control.BeginInvoke 根本不是一个调用on 的委托。它需要一个委托。
      【解决方案3】:

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

      • 启动委托以检查应用程序更新
      • 代理开始一个超时的网络请求
      • 如果发生错误/超时,或者如果应用程序是最新的,则该方法会简单地返回
      • 如果应用程序已过期,我会放置一条非窃取焦点的系统托盘消息,说明如此(除非有可用更新,否则没有系统托盘图标)

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

      【讨论】:

        猜你喜欢
        • 2012-01-20
        • 1970-01-01
        • 2011-06-29
        • 2016-08-31
        • 2013-06-25
        • 1970-01-01
        • 2020-09-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多