套接字编程的APM,EAP和TPL

Şaf*_*Gür 9 c# sockets design-patterns asynchronous task-parallel-library

我发现[...] Async和Begin [...] .net异步API之间存在差异,这个答案让我有点困惑.

谈到这些模式,斯蒂芬说:

大多数*异步方法(具有相应的*已完成事件)正在使用基于事件的异步模式.较旧(但仍然完全有效)的Begin*和End*是一种称为异步编程模型的模式.

Socket类是此规则的一个例外; 它的*异步方法没有任何相应的事件; 它本质上只是APM以避免过多内存分配的方式完成的.

我得到它使用*Async方法更有效,至少在套接字方面.但后来他提到任务并行库:

但是,APM和EBAP都被基于任务并行库的更灵活的方法所取代.由于TPL可以轻松地包装APM,因此较旧的类可能不会直接更新; 扩展方法用于为旧的APM方法提供Task等价物.

我在MSDN上发现了TPL和传统.NET异步编程,我知道TPL的基础知识,创建任务,取消,延续等等,但我仍然无法理解这些:

异步编程模型(APM)和基于事件的异步模式(EAP)相互比较的优势是什么?TPL如何轻松地包装 APM意味着APM和EAP都 TPL 取代

最重要的是:我应该在套接字编程中使用哪个;

  • APM?
  • EAP?
  • 任务包裹的APM或EAP?
  • TPL通过在任务中使用Socket类的阻塞方法?
  • 其他?

Gid*_*rth 7

TPL如何轻松地包装APM意味着APM和EAP都被TPL取代?

它没有.更新的APM和EAP将被替换为TAP(任务异步模式),或者在新的API中没有与此无关.我希望TAP能够以各种原因取代APM和EAP.我的主要原因是你为使用TAP编写的代码组成得更好.这样做.ContinueWith(/* ... */).ContinueWith(/* ... */)一般比读取相应的代码,你需要写链异步调用通过开始/结束的方法,即使你不考虑你可以传递给ContinueWith的选项,以确定是否延续应该运行好得多.TPL还为任务提供了各种组合器,例如WaitAllWaitAny,可以使某些场景更容易.通过async/await关键字进入C#和VB.NET的语言支持将使这更容易.

能够在TAP中包装APM使得更容易切换到此模式,因为这意味着您不必重写现有代码以使其适合新模型.

我应该在套接字编程中使用哪个?

我建议在Socket上使用TAP包装APM方法.除非您能够证明将Begin/End方法包装到Task中的额外开销是可伸缩/足够快的差异,否则我将利用TAP编码的简易性.


Ste*_*ary 5

吉迪恩给出了一个很好的答案;我只是想提供更多背景信息:

异步编程模型 (APM) 和基于事件的异步模式 (EAP) 相比有何优势?

APM 更为常见,并且具有相当严格定义的模式。例如,TPL 具有 APM 方法的通用包装器 ( TaskFactory.FromAsync),但它不能对 EAP 执行相同的操作,因为 EAP 没有严格定义。

EAP 有一个很大的优点:事件回调为您处理线程封送。因此,它们非常适合 UI ( BackgroundWorker) 的基本后台操作等。

TAP 结合了两方面的优点:默认的自动线程封送和严格定义的通用模式。它还为异步操作提供了一个很好的对象表示(Task)。

“TPL可以轻松包装APM”如何意味着“APM和EAP都正在被TPL取代”?

事实并非如此。

“然而,APM 和 EBAP 都被基于任务并行库的更加灵活的方法所取代。” - 意味着新代码不需要包含APM/EAP方法/事件;新代码应该包含 TAP 方法。

“由于 TPL 可以轻松包装 APM,因此旧类可能不会直接更新;扩展方法用于为旧 APM 方法提供任务等效项。” - 这意味着您可以使用以下命令将 TAP 方法添加到现有 APM 类型中TaskFactory.FromAsync:我认为 TPL 团队会采用这种方法,而不是修改 BCL 中的大量类。然而,我的这个猜想是错误的。出于性能原因,BCL/TPL 团队确实审查了整个框架,并将 TAP 方法直接添加到 .NET 类中,而不是使用扩展方法。新的 TAP 方法包含在 .NET 4.5 中,即将推出...

  • TAP 本身不进行线程封送。但是 TAP 与 `await` 结合使用就可以了。 (2认同)
  • 我认为这取决于“TAP”的定义。我在 TAP 中包含了 `async` 和 `await`。 (2认同)