高性能套接字上的异步等待与线程池与多线程(C10k 解决方案?)

Async-Await vs ThreadPool vs MultiThreading on High-Performance Sockets (C10k Solutions?)

我对 async-awaitpoolthread 真的很困惑。主要问题从这个问题开始:"What can I do when I have to handle 10k socket I/O?"(又名The C10k Problem)。

现在,我想应该还有其他人对处理 C10k 感到困惑。我的项目是我的游戏项目的专用(中央)服务器,它是 hub/lobby 服务器,例如 MCSG 的大厅或 COD 的配对服务器。我将执行登录操作、游戏服务器命令 executions/queries 和信息服务(如版本、补丁)。

最后一部分可能更具体地介绍了我的项目,但我确实需要一些关于多(重)数据处理的现实世界解决方案的好建议。

(也是,1k-10k-100k 连接处理取决于服务器硬件,但这是一个普遍问题)


关键点:Choosing Between the Task Parallel Library and the ThreadPool(MSDN 博客)


[附加] 想要了解我们在说什么的人可以阅读的好(基本)内容:

  1. Threads
  2. Async, Await
  3. ThreadPool
  4. BackgroundWorker

async/await 大致类似于您引用的文章中的 "Serve many clients with each thread, and use asynchronous I/O and completion notification" 方法。

虽然 asyncawait 本身不会导致任何额外的线程,但如果 async 方法在线程池上下文中恢复,它们将使用线程池线程。请注意,asyncThreadPool 的交互是高度优化的;非常怀疑您是否可以使用 ThreadThreadPool 获得相同的性能(有合理的开发时间)。

如果可以,我建议您使用现有协议 - 例如 SignalR。这将极大地简化您的代码,因为编写您自己的 TCP/IP 协议有很多 (many) 个陷阱。 SignalR 可以自托管或托管在 ASP.NET.

没有。如果我们使用.NET在4.5引入的异步编程模式,在大多数情况下我们不需要自己创建线程。编译器完成了开发人员过去常做的艰巨工作。创建一个新线程是昂贵的,需要时间。除非我们需要控制一个线程,否则“Task-based异步模式(TAP)”和“任务并行库(TPL)”已经足够用于异步和并行编程了。 TAP 和 TPL 使用任务。一般Task使用ThreadPool中的线程(线程池是.NET framework已经创建和维护的线程的集合。如果我们使用Task,大多数情况下我们不需要直接使用线程池。一个线程可以做更多的事情有用的东西。你可以阅读更多关于 Thread Pooling

您可以通过使用异步编程来避免性能瓶颈并增强应用程序的整体响应能力。异步对于可能阻塞的活动至关重要,例如当您的应用程序访问网络时。访问网络资源有时会很慢或延迟。如果这样的 activity 在同步进程中被阻塞,则整个应用程序必须等待。在异步进程中,应用程序可以继续执行其他不依赖于 Web 资源的工作,直到潜在的阻塞任务完成。

A​​wait 专门用于处理需要时间的事情,最典型的是 I/O 请求。传统上是在 I/O 请求完成时通过回调完成的。编写依赖于这些回调的代码是相当困难的,await 大大简化了它。 Await 只负责处理延迟,它不会做任何线程所做的事情。 await 表达式位于 await 关键字的右侧,用于完成工作。您可以将异步与 returns 任务的任何方法一起使用。 XxxxAsync() 方法只是 .NET 框架中用于需要时间的常见操作的预制方法。就像从网络服务器下载数据一样。

我会推荐你​​阅读Asynchronous Programming with Async and Await