在高性能套接字上使用Async-Await vs ThreadPool与MultiThreading(C10k解决方案?)

时间:2015-03-13 12:27:37

标签: c# multithreading sockets asynchronous threadpool

我对async-awaitpoolthread s感到非常困惑。主要问题始于这个问题:"当我必须处理10k插槽I / O时,我该怎么办?" (又名The C10k Problem)。

  • 首先,我尝试使用线程创建自定义池架构 使用一个主Queue和多个Thread来处理所有内容 传入的数据。理解这是一次很棒的经历 thread-safetymulti-threadingthread overkill 现在有async-await
  • 后来,我用async-await实现了一个简单的架构,但是我 无法理解为什么" async和await关键字不会导致 要创建的其他线程。" from MSDN)?我想那里 必须有一些thread才能完成BackgroundWorker等工作。
  • 最后,我用ThreadPool实现了另一个架构 看起来像是我的第一个自定义池。

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

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

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


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


[其他] 想要了解我们所谈论的内容的好(基本)内容:

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

2 个答案:

答案 0 :(得分:4)

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

的信息

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

Await专门用于处理花费时间的事情,最常见的是I / O请求。传统上,当I / O请求完成时,回调就完成了。编写依赖于这些回调的代码非常困难,等待大大简化它。等待处理延迟,它不执行任何线程所做的事情。 await表达式,即await关键字右侧的内容,是完成工作的原因。您可以对任何返回Task的方法使用Async。 XxxxAsync()方法只是.NET框架中预先生成的方法,用于需要时间的常见操作。就像从Web服务器下载数据一样。

我建议你阅读Asynchronous Programming with Async and Await

答案 1 :(得分:3)

async / await大致类似于“为每个线程提供服务的许多客户端,并在您引用的文章中使用异步I / O和完成通知”方法。

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

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