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

时间:2012-01-06 03:13:50

标签: c# multithreading networking

我正在使用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());   
        }

之后函数结束,线程结束。

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

        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();
    }

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

  

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

中断      

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

     

在System.Net.Sockets.NetworkStream.Read(Byte []缓冲区,Int32   offset,Int32 size)

     

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

     

在System.Net.Sockets.NetworkStream.Read(Byte []缓冲区,Int32   offset,Int32 size)

     

在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(),我仍然得到错误。

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

2 个答案:

答案 0 :(得分:2)

除了使用ReadLine之外,您不能只执行Read并构建String,直到检测到CrLf然后输出该更新日志。

ReadLine是一个阻塞调用,意味着它将位于那里并且如果连接关闭则总是出错。

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

我也可能会抓住特定的异常

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

答案 1 :(得分:2)

错误很好。如果您真的希望它消失,您可以在协议中包含“再见”命令。因此,如果服务器决定断开连接,则在断开连接之前,他会向客户端发送“再见”,因此客户端也会断开连接,并且大多数情况下不会抛出异常。但如果它被抛出,你仍然应该准备好抓住它。然后忽略它。