Я изучаю сетевой код и многопоточность в Monodevelop, используя C # с GTK #. Я никогда раньше не делал ни того, ни другого, а теперь мне нужно сделать и то, и другое одновременно.
Я использовал обучающую программу чата, в которой нет обработки ошибок, и обнаружил ошибку, которая возникает в клиенте каждый раз, когда я отключаюсь от сервера. Код, который находится в потоке, ожидающем сообщений, выглядит следующим образом, окруженный операторами 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. ---> Система.Net.Sockets.SocketException: A операция блокировки была прервана вызовом 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 [] buffer, 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 (), я все равно получаю сообщение об ошибке.
Насколько я могу судить, нет никаких побочных эффектов, вызванных простым обнаружением ошибки и продолжением работы, но это меня не устраивает. Нужно ли мне исправить эту ошибку, и если да, есть ли у кого-нибудь идеи?