如何创建自定义线程池

时间:2015-05-18 08:06:32

标签: c# multithreading sockets

我在.NET Framework 4.5中使用C#。我正在编写一个应该能够同时连接到任意多个客户端的服务器应用程序。所以我有一个线程会监听连接,然后它会将连接发送到后台线程进入循环等待消息。由于可支持的客户端连接的数量应该非常高,因此为每个连接生成一个新线程将不起作用。相反,我需要的是一个线程池。但是,我不想使用系统线程池,因为这些线程将在无限期地调用Socket.Select时被阻止,或者至少在它们托管的连接的生命周期中被阻塞。

所以我认为我需要一个自定义ThreadPool,我可以明确地将连接循环到。如何在C#中实现这一目标?

1 个答案:

答案 0 :(得分:2)

使用线程没有意义 - 这只是浪费资源。

相反,您希望使用异步I / O.现在,忽略网络所涉及的所有复杂性,基本思想是这样的:

async Task Loop()
{
    using(var client = new TcpClient())
    {
        await client.ConnectAsync(IPAddress.Loopback, 6536).ConfigureAwait(false);

        var stream = client.GetStream();

        byte[] outBuf = new byte[4096];

        // The "message loop"
        while (true)
        {
            // Asynchronously wait for the message
            var read = await stream.ReadAsync(outBuf, 0, outBuf.Length);

            // Handle the message, asynchronously send replies, whatever...
        }
    }
}

您可以为正在进行的每个连接运行此方法(不使用使用await - 非常重要)。处理该特定套接字的线程将在每个await上释放 - 该await的延续将发布在线程池线程上。

结果是,在任何给定时间使用的线程数量趋向于与可用的CPU核心等自我平衡,同时您可以一次轻松地为数千个连接提供服务。

请勿使用我发布的确切代码。您需要添加大量的错误处理代码等。安全可靠地处理网络非常棘手。