如果.NET Task.Run用于运行CPU绑定任务,那么启动IO绑定任务以在后台运行的正确方法是什么?

时间:2015-02-03 20:33:49

标签: c# .net multithreading task

我从头开始编写网络服务器应用程序,因此没有IIS或Windows窗体。我一直在使用Task.Run来切断对网络会话生命的控制,以便在后台运行。

像...一样的东西。

while (true)
{
    var tcpClient = tcpListener.Accept...
    Task.Run(() => ProcessSession(tcpClient));
}

......然后......

public async Task ProcessSession(TcpClient tcpClient)
{
    ...
    await tcpClient.GetStream().ReadAsync(...)
    ...
}

我希望当我在ProcessSession中对网络I / O进行异步/等待时,工作线程将被释放,直到I / O完成。

我发现我的服务器软件只有几百个连接陷入困境,到了客户端超时尝试连接的程度,或者如果他们连接起来,他们的网络吞吐量确实很慢。我希望每台服务器能处理数千个连接。

当我查看ThreadPool.Get(最大/可用)线程时,它看起来并没有那么多。 Process.GetCurrentProcess()。Threads.Count只有几十个,所以它并不像它是每个连接的一个线程。它只是陷入困境。

2 个答案:

答案 0 :(得分:1)

利用网络堆栈的内置异步是正确的解决方案,看起来就像你在使用TcpClient做的那样。

鉴于你已经陷入困境,"调查瓶颈在哪里。如果不知道问题是什么,没有人能解决性能问题。你的记忆空间是什么样的?时间花在哪里? perfmon说你的服务器进程发生了什么?

答案 1 :(得分:1)

如果ProcessSession确实没有阻止,那么您可以调用它:

while (true)
{
    var tcpClient = tcpListener.Accept...
    ProcessSession(tcpClient);
}

抛弃结果任务。请务必记录所有错误。

将名称更改为ProcessSessionAsync