System.IO.IOException when trying to terminate a thread

I am learning netcode and multithreading in Monodevelop using C # with GTK #. I have never done this before, and now I need to do everything at once.

I used a chat tutorial that has no error handling, and I found an error that occurs in the client every time I disconnect from the server. The code that sits in the thread listening for messages looks like this, surrounded by try / catch statements:

try { while (Connected) { if (!srReceiver.EndOfStream && Connected) { string temp = srReceiver.ReadLine(); // Show the messages in the log TextBox Gtk.Application.Invoke(delegate { UpdateLog(temp); }); } } } catch (Exception ex) { Console.WriteLine(ex.ToString()); } 

After which the function ends and the thread ends.

The code that ends the connection looks like this and works in the main thread:

  private void CloseConnection(string Reason) { // Show the reason why the connection is ending UpdateLog(Reason); // Enable and disable the appropriate controls on the form txtIp.Sensitive = true; txtUser.Sensitive = true; txtMessage.Sensitive = false; btnSend.Sensitive = false; btnConnect.Label = "Connect"; // Close the objects Connected = false; swSender.Close(); srReceiver.Close(); tcpServer.Close(); } 

And the above try / catch statements will catch this error:

System.IO.IOException: unable to read data from transport connection: blocking operation was interrupted by calling WSACancelBlockingCall. ---> System.Net.Sockets.SocketException: A lock operation was aborted by a call to WSACancelBlockingCall

in System.Net.Sockets.Socket.Receive (byte buffer [], Int32 offset, Int32 size, SocketFlags socketFlags)

in System.Net.Sockets.NetworkStream.Read (byte [] buffer, Int32 offset, Int32 size)

--- End of internal exception stack trace ---

in System.Net.Sockets.NetworkStream.Read (byte [] buffer, Int32 offset, Int32 size)

in System.IO.StreamReader.ReadBuffer ()

in System.IO.StreamReader.get_EndOfStream ()

in ChatClientGTK.MainWindow.ReceiveMessages () in g: \ Android \ Tutes \ ChatClientRemake \ ChatClientGTK \ MainWindow.cs: line 157

Now, as far as I can tell, when sRReciever.Close () occurs in the main thread, srReciever.ReadLine () is still trying to execute in the listen thread, where the problem lies, but even when I comment srReciever.Close (), I still I get an error.

As far as I can tell, there are no side effects caused by just catching a mistake and moving on, but in fact it is not. Does this mistake need to be fixed, and if so, does anyone have any ideas?

+6
source share
2 answers

Instead of using ReadLine, you cannot just read and assemble a line until CrLf is detected, and then output this to update the log.

ReadLine is a blocking call, meaning that it will sit there and will always be an error if the connection is closed.

Otherwise, you can simply ignore the error. I know what you mean when you say that it doesn’t work, but if someone else cannot enlighten me, I don’t see that it is leaking resources, and if this is an expected error, then you can handle it properly.

Also I will probably catch a specific exception

 catch (IOException ex) { Console.WriteLine(ex.ToString()); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } 
+2
source

The error is in order. If you really want him to leave, you can include the bye command in your protocol. Thus, if the server decides to disconnect, just before disconnecting it sends a "bye" to the client, so the client also disconnects, and most of the chances are that the exception will not be thrown. But you still have to be prepared to catch him if he is ever abandoned. And then ignore it.

+2
source

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


All Articles