尝试结束线程时出现System.IO.IOException异常

Exc*_*ent 6 c# networking multithreading

我正在使用C#和GTK#在Monodevelop中学习网络代码和多线程.我以前从未做过,现在我发现自己需要同时做两件事.

我使用了一个没有错误处理的教程聊天程序,我发现每次与服务器断开连接时都会在客户端发生错误.位于侦听消息的线程中的代码如下所示,由try/catch语句包围:

            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());   
        }
Run Code Online (Sandbox Code Playgroud)

之后函数完成并且线程结束.

结束连接的代码如下所示,并在主线程上运行:

        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();
    }
Run Code Online (Sandbox Code Playgroud)

上面的try/catch语句捕获了这个错误:

System.IO.IOException:无法从传输连接读取数据:通过调用WSACancelBlockingCall中断阻塞操作.---> System.Net.Sockets.SocketException:调用WSACancelBlockingCall中断了阻塞操作

在System.Net.Sockets.Socket.Receive(Byte []缓冲区,Int32偏移量,Int32大小,SocketFlags socketFlags)

在System.Net.Sockets.NetworkStream.Read(Byte []缓冲区,Int32偏移量,Int32大小)

---内部异常堆栈跟踪结束---

在System.Net.Sockets.NetworkStream.Read(Byte []缓冲区,Int32偏移量,Int32大小)

在System.IO.StreamReader.ReadBuffer()

在System.IO.StreamReader.get_EndOfStream()

在ChatClientGTK.MainWindow.ReceiveMessages()中的g:\ Android\Tutes\ChatClientRemake\ChatClientGTK\MainWindow.cs:第157行

现在,据我所知,当srReciever.Close()在主线程中发生时,srReciever.ReadLine()仍然试图在侦听线程中执行,这就是问题所在,但即使我注释掉了srReciever .Close(),我仍然得到错误.

据我所知,只有抓住错误并继续前进不会产生任何副作用,但这并不适合我.我是否需要修复此错误,如果有,是否有人有任何想法?

Ada*_*ley 2

您不能只执行读取并构建字符串,直到检测到 CrLf,然后将其输出到更新日志,而不是使用 ReadLine。

ReadLine 是一个阻塞调用,这意味着如果连接关闭,它会坐在那里并且始终出错。

否则你可以忽略该错误。我知道当你说它不正确时你的意思,但除非其他人可以启发我,否则我不认为有任何资源泄漏,如果这是一个预期的错误,那么你可以适当地处理它。

我也可能会捕捉到特定的异常

catch (IOException ex)
        {
            Console.WriteLine(ex.ToString());
        }
catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }
Run Code Online (Sandbox Code Playgroud)