Zachary Turner
Zachary Turner

Reputation: 772

How to create a custom thread pool

I'm using C# with .NET Framework 4.5. I'm writing a server application that should be able to connect to arbitrarily many clients at once. So I have one thread that will listen for connections, and then it will send the connection to a background thread to go into a loop waiting for messages. Since the number of supportable client connections should be very high, spawning a new thread for every connection won't work. Instead what I need is a thread pool. However, I don't want to use the system thread pool because these threads will essentially be blocked in a call to Socket.Select indefinitely, or at least for the life of the connections they host.

So I think I need a custom ThreadPool that I can explicitly round-robin the connections over to. How to achieve this in C#?

Upvotes: 0

Views: 948

Answers (1)

Luaan
Luaan

Reputation: 63742

There's no point in using threads for this - that's just wasting resources.

Instead, you want to use asynchronous I/O. Now, ignoring all the complexities involved with networking, the basic idea is something like this:

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...
        }
    }
}

You can run this method for each of the connection you're making (without using await - very important). The thread handling that particular socket will be released on every await - the continuation of that await will be posted on a thread-pool thread.

The result being, the amount of threads used at any given time will tend to self-balance with the available CPU cores etc., while you can easily service thousands of connections at a time.

Do not use the exact code I posted. You need to add tons of error-handling code etc. Handling networking safely and reliably is very tricky.

Upvotes: 2

Related Questions