Given you mention C#, you already have some very good tools in place you should be leveraging for for this. Specifically the async socket functions and the thread pool work together to give you a very fast way to process connections without blocking a large number of threads. While waiting for an async function to complete, .NET will release the thread back to the thread pool so that it can be used to process other connections. I suggest you have a read up on them and make sure you understand how the two interact.
If your server is running a standard main loop type arrangement for the actual game simulation you will want some way to communicate with it from the async handlers. Personally I make use of .NETs ConcurrentQueue. The items posted into the queue include metadata on which client sent the message etc.
This is not necessarily the fastest way to process a single message, but it is designed to scale nicely to a large number of them. Here are some starting points for you:
Between these you get much of what the article is discussing.
What you are suggesting is what I'm trying to remedy.
Your suggestion (or assumption) with a main thread and a lockless queue that each connection will post messages to might run into problems related to context switching. This is outlined in one of the articles I referenced. Another issue with this design is who returns the result to the client? You will most likely have another queue for this task, which will incur another context switch. I'm trying to get rid of these context switches by using the threads as workers, as recommended by the article. This design, however, might not conform to best practise (atleast not when seen from high cohesion/low coupling point of view..), but I'm trying to make the server as efficient as possible and am thus willing to make a few sacrifices for this.
I intend on using what you mention in your post (async), but the question is related to who actually makes the computation. Is it a dedicated thread (by your assumption) or should every thread that handles a connection take care of this themselves (to avoid context switches and data transfers among threads).
Thanks for the links!