2012-01-06 43 views
6

Tôi đang học netcode và đa luồng trong Monodevelop, sử dụng C# với GTK #. Tôi chưa bao giờ làm trước đây, và bây giờ tôi thấy mình cần phải làm cả hai cùng một lúc.Ngoại lệ System.IO.IOException khi cố gắng kết thúc chủ đề

Tôi đã sử dụng chương trình trò chuyện hướng dẫn không xử lý lỗi và tôi đã gặp lỗi xảy ra trong ứng dụng khách mỗi lần tôi ngắt kết nối khỏi máy chủ. Mã nằm trong một chuỗi đang nghe tin nhắn như sau, được bao quanh bởi các câu lệnh 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()); 
     } 

Sau đó chức năng kết thúc và chỉ kết thúc.

Mã kết thúc kết nối trông như thế này, và chạy trên các chủ đề chính:

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

Và try/catch câu nói trên bắt lỗi này:

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

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

at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)

--- End of inner exception stack trace ---

at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)

at System.IO.StreamReader.ReadBuffer()

at System.IO.StreamReader.get_EndOfStream()

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

Bây giờ, như xa như tôi có thể nói, khi srReciever.Close() xảy ra trong chủ đề chính, srReciever.ReadLine() vẫn đang cố gắng thực hiện trong chuỗi nghe, đó là nơi mà vấn đề nằm, nhưng ngay cả khi tôi nhận xét ra srReciever.Close() , Tôi vẫn nhận được lỗi.

Theo như tôi có thể nói, không có tác dụng phụ gây ra bởi chỉ bắt lỗi và di chuyển, nhưng điều đó không thực sự phù hợp với tôi. Tôi có cần khắc phục lỗi này không và nếu có, có ai có ý tưởng gì không?

+1

Một ví dụ khác về ngoại lệ được ném để cho biết điều kiện không ngoại lệ. Hầu hết mọi người xem xét rằng thiết kế API xấu, nhưng với .NET BCL nó phổ biến. –

Trả lời

2

Thay vì sử dụng ReadLine, bạn không thể chỉ đọc và xây dựng chuỗi cho đến khi một CrLf được phát hiện rồi xuất ra để cập nhật nhật ký.

ReadLine là một cuộc gọi chặn có nghĩa là nó sẽ ngồi đó và luôn luôn lỗi nếu kết nối được đóng lại.

Nếu không, bạn chỉ có thể bỏ qua lỗi. Tôi biết ý bạn là gì khi bạn nói nó không đúng nhưng trừ khi bất cứ ai khác có thể khai sáng cho tôi, tôi không thấy rằng có bất kỳ sự rò rỉ nào trong tài nguyên do nó và nếu đó là lỗi dự kiến ​​thì bạn có thể xử lý nó một cách thích hợp .

Ngoài ra tôi có lẽ sẽ bắt ngoại lệ cụ thể

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

Chỉ muốn thêm rằng bạn vẫn cần phải xử lý lỗi đó bất kể bạn sử dụng phương pháp nào vì bạn sẽ cần phải tính đến kết nối mạng bị ngắt. –

+0

Tuyệt vời, đó là điều tôi nghi ngờ. Tôi sẽ bắt được ngoại lệ đặc biệt đó và tiếp tục cuộc sống của tôi. Cảm ơn! – Excrubulent

2

Lỗi này là tốt. Nếu bạn thực sự muốn nó biến mất, bạn có thể bao gồm lệnh "tạm biệt" trong giao thức của mình. Vì vậy, nếu máy chủ quyết định ngắt kết nối, ngay trước khi ngắt kết nối, anh ta gửi một "bye" tới máy khách, vì vậy máy khách ngắt kết nối, và hầu hết các cơ hội là ngoại lệ sẽ không bị ném. Nhưng bạn vẫn nên chuẩn bị để bắt nó nếu nó bị ném. Và sau đó bỏ qua nó.

+0

Tôi đã không dành nhiều thời gian trên mã máy chủ - tôi vẫn phải dừng nó khỏi bị rơi bất cứ khi nào một khách hàng bất ngờ ngắt kết nối. Tôi tưởng tượng đó là một loại điều tương tự, trong đó một ngoại lệ bị ném vào một tình huống khá bình thường. Ngoài ra, ngoại lệ trong máy khách được ném không khi máy chủ ngắt kết nối, nhưng khi máy khách quyết định ngắt kết nối. Tôi sẽ viết lại cả hai chương trình trước khi tôi thực sự cố gắng làm bất cứ điều gì với chúng, mặc dù - Tôi thích viết mọi dòng để tôi quen thuộc với chính xác mã đang làm. – Excrubulent

Các vấn đề liên quan