决定何时实现基于事件的异步模式

基于事件的异步模式可用于公开类的异步行为。 通过引入此模式,.NET 定义了两种用于公开异步行为的模式:基于 System.IAsyncResult 接口的异步模式和基于事件的模式。 本文介绍何时适合实现这两种模式。

有关使用IAsyncResult接口进行异步编程的详细信息,请参阅异步编程模型(APM)。

一般原则

通常,应尽可能使用基于事件的异步模式公开异步功能。 但是,存在一些基于事件的模式无法满足的要求。 在这些情况下,除了基于事件的模式外,可能需要实现 IAsyncResult 模式。

注释

通常情况下, 很少有 IAsyncResult 模式的实现不伴随事件驱动模式的实现。

准则

以下列表描述了何时应实现基于事件的异步模式的准则:

  • 使用事件驱动模式作为默认 API 来呈现类的异步行为。

  • 当类主要用于客户端应用程序(例如 Windows 窗体)时,请勿公开 IAsyncResult 模式。

  • 只有在满足要求时才公开 IAsyncResult 模式。 例如,与现有 API 的兼容性可能需要公开 IAsyncResult 模式。

  • 请勿在不公开基于事件的模式的情况下公开 IAsyncResult 模式。

  • 如果必须公开模式 IAsyncResult ,请将其作为高级选项进行公开。 例如,如果生成代理对象,则默认生成基于事件的模式,并具有生成 IAsyncResult 模式的选项。

  • 在你的 IAsyncResult 模式实现上构建基于事件的模式实现。

  • 避免在同一类上公开基于事件的模式和 IAsyncResult 模式。 请对“高级”类公开基于事件的模式,并对“低级”类公开 IAsyncResult 模式。 例如,将组件上的 WebClient 基于事件的模式与 IAsyncResult 类上的 HttpRequest 模式进行比较。

    • 当兼容性需要该模式时,公开同一类上的基于事件的模式和 IAsyncResult 模式。 例如,如果已发布使用模式的 IAsyncResult API,则需要保留 IAsyncResult 模式以实现向后兼容性。

    • 如果生成的对象模型复杂性超过分离实现的好处,则公开同一类上的基于事件的模式和 IAsyncResult 模式。 最好在单个类上公开这两种模式,而不是避免公开基于事件的模式。

    • 如果必须对一个类公开基于事件的模式和 IAsyncResult 模式,请将 EditorBrowsableAttribute 设置为 Advanced,以将 IAsyncResult 模式实现标记为高级功能。 这表示在设计环境中(如 Visual Studio IntelliSense),不显示 IAsyncResult 属性和方法。 这些属性和方法仍然完全可用,但通过 IntelliSense 工作的开发人员对 API 具有更清晰的视图。

除了基于事件的模式外还公开 IAsyncResult 模式的条件

虽然基于事件的异步模式在前面提到的方案中有很多好处,但它确实有一些缺点,如果性能是最重要的要求,应该注意这一点。

有三个场景是基于事件的模式未能像 IAsyncResult 模式那样有效地解决:

可以使用基于事件的模式来解决这些方案,但这样做比使用 IAsyncResult 模式更繁琐。

开发人员经常将 IAsyncResult 模式用于通常具有非常高的性能要求的服务。 例如,轮询完成状态就是一种高性能服务器技术。

此外,基于事件的模式比 IAsyncResult 模式效率低,因为它会创建更多对象,特别是 EventArgs因为它跨线程同步。

如果决定使用 IAsyncResult 模式,以下是一些建议供你参考:

另请参阅