Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Async-Await vs ThreadPool vs MultiThreading on High-Performance Sockets (C10k Solutions?)

I'm really confused about async-awaits, pools and threads. The main problem starts with this question: "What can I do when I have to handle 10k socket I/O?" (aka The C10k Problem).

  • First, I tried to make a custom pooling architecture with threads that uses one main Queue and multiple Threads to process all incoming datas. It was a great experience about understanding thread-safety and multi-threading but thread is an overkill with async-await nowadays.
  • Later, I implemented a simple architecture with async-await but I can't understand why "The async and await keywords don't cause additional threads to be created." (from MSDN)? I think there must be some threads to do jobs like BackgroundWorker.
  • Finally, I implemented another architecture with ThreadPool and it looks like my first custom pooling.

Now, I think there should be someone else with me who confused about handling The C10k. My project is a dedicated (central) server for my game project that is hub/lobby server like MCSG's lobbies or COD's matchmaking servers. I'll do the login operations, game server command executions/queries and information serving (like version, patch).

Last part might be more specific about my project but I really need some good suggestions about real world solutions about multiple (heavy) data handling.

(Also yes, 1k-10k-100k connection handling depending on server hardware but this is a general question)


The key point: Choosing Between the Task Parallel Library and the ThreadPool (MSDN Blog)


[ADDITIONAL] Good (basic) things to read who wants to understand what are we talking about:

  1. Threads
  2. Async, Await
  3. ThreadPool
  4. BackgroundWorker
like image 323
MFatihMAR Avatar asked Mar 13 '15 12:03

MFatihMAR


2 Answers

async/await is roughly analogous to the "Serve many clients with each thread, and use asynchronous I/O and completion notification" approach in your referenced article.

While async and await by themselves do not cause any additional threads, they will make use of thread pool threads if an async method resumes on a thread pool context. Note that the async interaction with ThreadPool is highly optimized; it is very doubtful that you can use Thread or ThreadPool to get the same performance (with a reasonable time for development).

If you can, I'd recommend using an existing protocol - e.g., SignalR. This will greatly simplify your code, since there are many (many) pitfalls to writing your own TCP/IP protocol. SignalR can be self-hosted or hosted on ASP.NET.

like image 136
Stephen Cleary Avatar answered Nov 12 '22 05:11

Stephen Cleary


No. If we use asynchronous programming pattern that .NET introduced in 4.5, in most of the cases we need not to create manual thread by us. The compiler does the difficult work that the developer used to do. Creating a new thread is costly, it takes time. Unless we need to control a thread, then “Task-based Asynchronous Pattern (TAP)” and “Task Parallel Library (TPL)” is good enough for asynchronous and parallel programming. TAP and TPL uses Task. In general Task uses the thread from ThreadPool(A thread pool is a collection of threads already created and maintained by .NET framework. If we use Task, most of the cases we need not to use thread pool directly. A thread can do many more useful things. You can read more about Thread Pooling

You can avoid performance bottlenecks and enhance the overall responsiveness of your application by using asynchronous programming. Asynchrony is essential for activities that are potentially blocking, such as when your application accesses the web. Access to a web resource sometimes is slow or delayed. If such an activity is blocked within a synchronous process, the entire application must wait. In an asynchronous process, the application can continue with other work that doesn't depend on the web resource until the potentially blocking task finishes.

Await is specifically designed to deal with something taking time, most typically an I/O request. Which traditionally was done with a callback when the I/O request was complete. Writing code that relies on these callbacks is quite difficult, await greatly simplifies it. Await just takes care of dealing with the delay, it doesn't otherwise do anything that a thread does. The await expression, what's at the right of the await keyword, is what gets the job done. You can use Async with any method that returns a Task. The XxxxAsync() methods are just precooked ones in the .NET framework for common operations that take time. Like downloading data from a web server.

I would recommend you to read Asynchronous Programming with Async and Await

like image 4
Mohit S Avatar answered Nov 12 '22 04:11

Mohit S