Why is asynchronous mode better than synchronous when processing client requests?

I have a client-server project and I was looking for the best way to handle requests from clients. Some people have reported that asynchronous mode is better than synchronous and thread pool mode.
Why is my question? And are there any flaws in asynchronous mode?

+4
source share
6 answers

Yes, asynchronous requests can often be processed without the expense of a thread. The operating system has special support for them, such as overlapping I / O and shutdown ports. What they basically do is use the kernel thread consumption, which is necessary in any case, because the driver must be able to process multiple requests from multiple user-mode programs. The .NET framework easily uses this in its BeginXxx () methods.

Using threadpool threads is also cheap, but you are subject to the behavior of the thread scheduler. Which doesn’t really like to start more TP streams, then there are cores. TP threads should never be used for code that may remain locked for a while, which is quite typical for CS tasks such as creating a connection.

Error handling is very difficult in asynchronous code. Usually you have very little context when the EndXxxx () method throws an exception. This happens in the callback thread, very far from the main logic. It’s good when you can shrug your shoulders, “it didn’t happen, let's write it down”, full of bedlam and blush, when the state of the program depends on it. Always choose synchronous mode in the latter case.

+7
source

You do not want to block the user interface. With asynchronous operation, you can do other things, waiting for a server response.

+2
source

Asynchronous mode allows you to continue processing, while synchronous mode keeps you waiting.

+2
source

One of the drawbacks of synchronous operations is IMO that you cannot interrupt them - for example, when your server application calls the synchronous WaitForConnection () method and the client does not connect, you cannot stop waiting ...

For example, try looking. What is a good way to disable threads blocked on NamedPipeServer # WaitForConnection?

+1
source

To "mark" the answer "Hans": independence of input-output operations from flows allows much more significant scaling; tens of thousands of outstanding queries are possible, which simply cannot be accomplished using threads.

In addition, when you start by considering the complexity of error handling in protocol design , it turns out that the complexity of asynchronous methods is much less than the complexity of correctly writing synchronous code. The most synchronous socket code looks simpler, but actually contains subtle errors.

Asynchronous methods are also important to prevent deadlock situations if both sides send more data than they read; see this blog post for further discussion.

If you want the reliability and (most) performance advantages of asynchronous I / O in a thread-safe shell (with simpler error handling), consider the Nito.Async library .

+1
source

On a synchronous server, you must handle locks when accessing your data structures (if updates are present), and this takes time and code (and this is the source of hard-to-reach errors). In addition, the presence of many (for example, thousands) of threads creates technical problems in many implementations (for example, for stack distribution), and if the server is tied to IO, these threads almost all sleep (waiting for the network) and simply lose memory.

Using an asynchronous model in a single thread, you can ignore the lock problem (this means that your processing is as fast as it can be received), and you only use the memory needed for clients (there is only one stack).

However, multi-core machines are now quite common, so part of the advantage is lost (because you have to block if you modify the general data structure). Probably the best performance can be achieved by using a balancer in front of N asynchronous servers, where N is the optimal number of threads for your environment.

The bad side of the asynchronous approach is that depending on your tools, the code can be pretty ugly and hard to understand, and that if the calculation is not trivial and by mistake your processing enters an endless loop, the entire asynchronous server will not respond (therefore, probably watchdog timer should be added).

0
source

Source: https://habr.com/ru/post/1314493/


All Articles