10

我发现[...]Async 和 Begin[...] .net 异步 API 之间的区别问题,但这个答案让我有点困惑。

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

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

Socket 类是这个规则的一个例外;它的 *Async 方法没有任何对应的事件;它本质上只是为了避免过多的内存分配而完成的 APM。

我认为使用 *Async 方法效率更高,至少在套接字方面是这样。但随后他提到了任务并行库:

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

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

异步编程模型 (APM) 和基于事件的异步模式 (EAP) 相比有哪些优势?TPL如何轻松包装APM 意味着 APM 和 EAP 都将被TPL 取代?

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

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

2 回答 2

7

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

它没有。APM 和 EAP 是否会被 TAP(任务异步模式)取代或不在新的 API 中与此无关。出于各种原因,我希望 TAP 取代 APM 和 EAP。对我来说,主要原因是您为使用 TAP 编写的代码编写得更好。执行.ContinueWith(/* ... */).ContinueWith(/* ... */)通常比通过 Begin/End 方法链接异步调用所需编写的相应代码要好得多,即使您不考虑可以传递给 ContinueWith 以确定是否应该运行延续的选项。TPL 还为任务提供了各种组合器,例如WaitAllWaitAny,这可以使某些场景变得更加容易。通过 async/await 关键字在 C# 和 VB.NET 中提供的语言支持将使这更加容易。

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

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

我建议使用 TAP 在 Socket 上包装 APM 方法。除非您可以证明将 Begin/End 方法包装到 Task 中的额外开销是可扩展/是否足够快之间的区别,否则我会利用 TAP 编码的简易性。

于 2012-07-03T04:20:19.213 回答
4

基甸有一个很好的答案。我只是想提供更多背景信息:

异步编程模型 (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 方法提供 Task 等效项。” - 意味着您可以使用 ; 将 TAP 方法添加到现有的 APM 类型TaskFactory.FromAsync;我认为 TPL 团队会采用这种方法,而不是修改 BCL 中的大量类。然而,我在这个猜想中是错误的。出于性能原因,BCL/TPL 团队确实审查了整个框架并将 TAP 方法直接添加到 .NET 类中,而不是使用扩展方法。新的 TAP 方法包含在 .NET 4.5 中,即将推出......

于 2012-07-15T00:58:42.007 回答