Do I need to use async Begin / End methods, if already in a separate thread?

Trying to figure out whether to use async methods or not, for example:

and

unlike their synchronous versions of TcpListener.AcceptTcpClient and NetworkStream.Read . I looked at related topics, but I'm still a little unsure of one thing:

Question: The main advantage of using the asynchronous method is that the GUI is not blocked. However, these methods will be called separate threads of the Task , since this does not threaten this. In addition, TcpListener.AcceptTcpClient blocks the thread until a connection is established, so there are no unnecessary processor cycles. Since this is so, why do so many recommend using asynchronous versions? It looks like in this case the synchronous versions will be superior?

In addition, another disadvantage of using asynchronous methods is the increased complexity and constant casting of objects. For example, you need to do the following:

 private void SomeMethod() { // ... listener.BeginAcceptTcpClient(OnAcceptConnection, listener); } private void OnAcceptConnection(IAsyncResult asyn) { TcpListener listener = (TcpListener)asyn.AsyncState; TcpClient client = listener.EndAcceptTcpClient(asyn); } 

In contrast to this:

TcpClient client = listener.AcceptTcpClient();

It also seems that there will be much more overhead for asynchronous versions due to the need to create another thread. (Basically, each connection will have a stream, and then when reading this stream there will also be a different stream. Threadception!)

In addition, there is boxing and unboxing TcpListener and overhead associated with the creation, management and closure of these additional threads.

Basically, where there are usually separate streams for processing individual client connections, now there is an additional stream for each type of operation performed (reading / writing stream data and listening for new connections on the server)

Please correct me if I am wrong. I'm still new to streaming, and I'm trying to figure it all out. However, in this case, it seems like using conventional synchronous methods, and just blocking the thread would be the optimal solution?

+6
source share
2 answers

TcpListener.AcceptTcpClient blocks the thread until a connection is established, so there are no unnecessary processor cycles.

But also no work will be done. Thread is a very expensive object of the operating system, about the most expensive. Your program consumes a megabyte of memory without use when the thread blocks when requesting a connection.

However, these methods will be called in separate task flows, since this does not threaten this.

The task is also not a good solution, it uses the threadpool thread, but the thread is blocked. The threadpool manager tries to keep the number of TP threads running equal to the number of processor cores on the machine. This will not work well when the TP stream is blocked for a long time. This prevents other TP threads that are waiting in line from doing other useful work.

BeginAcceptTcpClient () uses the so-called I / O completion callback. System resources are not consumed while listening to the socket. As soon as a connection request arrives, the operating system launches APC (asynchronous procedure call), which captures the threadpool thread to perform a callback. The stream itself is used, as a rule, in a few microseconds. Very effective.

This kind of code will be much simpler in the next version of C # with the following asynchronous and pending keywords. Perhaps the end of the year.

+4
source

If you call AcceptTcpClient() on any thread, that thread is useless until you get a connection.

If you call BeginAcceptTcpClient() , the calling thread can stop immediately without losing the thread.

This is especially important when using ThreadPool (or TPL) as they use a limited number of pool threads.
If you have too many threads waiting for operations, you can run out of threadpool threads, so new work items will have to wait until one of the other threads ends.

+3
source

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


All Articles