How to disable a stream that contains a blocking call to NetworkStream.Read

I am looking at code that was not written by me myself, and I am trying to understand what causes the application to crash.

I think that maybe it comes down to how he manages resources and manages flows.

The main parent thread creates a new application-level client (TCPMonitor), which then creates another class that processes TCP cells (TCPListen). This class spawns a new thread loop, which creates a new TCP socket client, reads the network stream on that socket, and then causes a synchronous Read () lock.

However, if a network error message occurs, the exception falls into the TCPListen stream loop and the event is returned back to the native TCPMonitor class. Then TCPMonitor checks to see if it contains an active instance of TCPListen, and if it calls Dispose () and sets the instance to Null.

Will TCPListen Read () still block the call? If this is the case, how can I guarantee that a Dispose call from the parent thread will break the child thread from the blocking call and correctly remove the thread and socket?

+4
source share
3 answers

Turn off the socket for input. This will unlock the reading and make it receive an EOS indication, regardless of the form used in the API. Since you are on Windows, this will also cause the other end to communicate if it continues to send. (This behavior is platform dependent.)

+1
source

You did not mention the actual calls to the C # API that your code uses, but assuming that this is one of the many Get methods in the Socket base object, you are correct that it will block endlessly on the binding if the timeout is not set ( ReceiveTimeout ) on the Socket object.

After installation, it will return if no data is received during this time. Then you can put the Receieve call in a loop on some logic, you can set from the outside to stop the thread, to stop.

Update:

Instead of blocking the stream when the synchronous Read call, you can use DataAvailable to query NetworkStream in a loop to find out if there is anything to read instead?

+1
source

How about using asynchronous calls (like BeginReceive ) instead of blocking calls and waiting for a thread on an object to say that it has stopped? Create something like ManualResetEvent and a thread will wait on it. An event signal is from the main thread, and when the listening thread wakes up, it can close the socket.

Note that when calling a data callback delegate, another BeginReceive call must be made if the stream needs to receive additional data. Check out the BeginReceive description here: http://msdn.microsoft.com/en-us/library/dxkwh6zw

+1
source

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


All Articles