C#套接字性能.Net 4.5 Async vs [...] Async vs Begin [...]

时间:2014-06-11 23:51:36

标签: c# performance sockets asynchronous

目前,根据我的研究,有三种方法可以异步使用套接字:

.Net 4.5异步示例:Using .Net 4.5 Async Feature for Socket Programming(第二篇文章)

[...]异步:http://msdn.microsoft.com/en-us/library/system.net.sockets.socketasynceventargs.aspx

开始[...]:http://msdn.microsoft.com/en-us/library/5w7b7x5f(v=vs.110).aspx

我对所有选项非常困惑.Net提供了使用异步套接字。我为什么要使用其中一个?有数千个同时连接的性能有什么更好的选择?

4 个答案:

答案 0 :(得分:9)

使用SocketAsyncEventArgs的方法与底层Windows技术(I / O完成端口)最匹配。它们本质上是一个裸机包装器,旨在执行零分配并以不太友好的API为代价提取最高性能。这具有更紧密耦合的代码的缺点,因为它没有实现任何标准Stream API。其他异步套接字方法都包装了这个。

使用Begin / End对的方法正在使用所谓的异步编程模型(APM)。 APM是.NET的原始异步模型。如果你使用半翘曲的话,很容易写出意大利面条代码,但是一旦你有一些经验,它就会起作用并且相当简单。但是,他们不应该在现代.NET中看到太多用途,因为我们有更容易和更好的表现:

返回Task的方法正在使用基于任务的异步模式(TAP)。任务是对APM的纯粹升级:它们更灵活,更易于编写,并且通常应具有相同或更好的性能。与语言集成的async / await结合使用后,您可以编写性能卓越且易于理解和维护的代码。

tl; dr 使用Task方法,除非您有极端性能要求。然后使用SocketAsyncEventArgs方法。不要使用APM方法。

答案 1 :(得分:5)

  

有更好的选择可以同时拥有成千上万的表现   连接?
  ......   关于Begin [...]的好奇心。如果我有一个MMORPG服务器在哪里   一个连接相互交互以进行位置更新,   动画,效果(基本的MMORPG机制),数字,这会   是“负载很重的服务器”? 200~300个同时连接?

在服务器端,您可以从使用任何异步套接字API(初始/结束样式APM,基于事件的EAP或基于Task的{​​{3}}个。这是因为与使用同步API相比,您将阻止更少的线程。因此,更多线程可用于同时向服务器提供其他传入请求,从而提高其可伸缩性。

最有可能的是,您不会看到使用TAP套接字API而不是其APM或EAP类似物的任何性能优势。但是,与APM或EAP相比,TAP API模式更容易开发。与async/await一起使用时,它会生成更短,更易读且更不容易出错的代码。您将获得自然的伪线性代码流,这是APM回调或EAP事件处理程序无法实现的。如果您找不到基于Task的正确套接字API,则始终Begin/End来自Task.FromAsync APM API Task(或来自EAP API,请检查{ {3}})。

对于客户端UI应用,可扩展性并不重要,但TAP模式还有另一个好处。通过很少的努力,它有助于使您的UI响应,因为您不会阻止UI线程(通常在等待同步调用的结果时发生)。这不是特定于基于Task的套接字API,它适用于任何基于Task.Delay()的API,例如Stream.ReadAsync()async/await

有关C#中异步编程的一些好的阅读材料,请查看{{1}}标签wiki:

TAP

答案 2 :(得分:1)

如果您有机会使用.NET 4.5和async / await,我完全推荐它。

基本上有这些在.NET中进行多线程处理的方法:

  1. 发。
  2. ThreadPool.QueueWorkItem。
  3. XXXAsync方法和XXXCompleted事件。
  4. BeginXXX和EndXXX方法。
  5. 任务并行库。
  6. 异步/ AWAIT
  7. 第一个是原始线程,您应该避免使用该选项,因为创建线程是一项昂贵的操作。其余的,只是使用ThreadPool的不同方式,这是一个负责维护可用于安排任务的线程集合的工具,产生比第一个选项更好的性能。

    使用不同的语法,但对我来说,最清楚的是async / await。我最近创建了WebSocket connector using sockets and asyn/awaitthe performance is quite good。从技术上讲,async / await并没有给你带来性能提升,但是代码的清晰度将允许你简化应用程序的方法,与基于continuation的混乱代码相比,这可能会带来良好的性能提升。

答案 3 :(得分:1)

首先,您可能希望在MSDN上查看此article,了解.NET中各种异步编程机制之间的差异。

Begin[…]是第一个使用APM(异步编程模型)的异步套接字实现。它将回调作为其参数之一。虽然与较新的方法相比有些过时,但如果你不介意处理回调和它们可以创建的混乱代码,这种方法很好。由于state对象,还有一些与此相关的额外开销,在负载很重的服务器上,这可能开始成为一个问题。

[…]Async使用较新的基于事件的模型,也是一种较轻的实现,可帮助解决Begin[…]带来的高流量问题。这种方式运行良好,但如果你不小心也可能导致代码混乱。哦,是的,你可以阅读有关here的错误,但除非你正在构建一个性能非常高的软件,否则你可能不会关心它。

基于任务的异步编程(TPL)是最新的机制,在async / await关键字的帮助下,可以提供与[…]Async相关的大部分(如果不是全部)效率,同时提供更容易理解码。此外,使用Tasks,一次等待多个操作完成要容易得多。重要的是要注意,虽然有几个本机.NET函数实现了TPL并返回Task,但还没有一个用于Socket操作。有一些如何在线进行此操作的示例,但它需要一些额外的工作。