Я пытаюсь разобраться в тонкостях чтения из NetworkStream и понять различные способы возникновения проблем. У меня есть следующий код:
public async Task ReceiveAll()
{
var ns = this.tcp.GetStream();
var readBuffer = new byte[1000];
while (true)
{
int bytesRead;
try
{
bytesRead = await ns.ReadAsync(readBuffer, 0, readBuffer.Length);
if (bytesRead == 0)
{
// Remote disconnection A?
break;
}
}
catch (IOException)
{
// Remote disconnection B?
break;
}
catch (ObjectDisposedException)
{
// Local disconnection?
break;
}
/*Do something with readBuffer */
}
}
Я отметил в коде три точки, где программа говорит: «Что-то пошло не так, продолжать нет смысла».
«Локальное отключение» не является чем-то неправильным, это произойдет, когда я локально закрою сокет, что является единственным способом выхода из цикла при нормальных обстоятельствах. Я не думаю, что что-то еще может вызвать это, поэтому я думаю, что могу просто проглотить исключение.
Две точки «Удаленное отключение» - это то, в чем я не уверен. Я знаю, что ReadAsync вернет 0, если соединение будет разорвано удаленно (A), но в некоторых случаях также срабатывает IOException. Если мой удаленный клиент является консолью С#, то закрытие сокета, по-видимому, приводит к «А», а закрытие окна консоли, похоже, к «Б». Я не уверен, что понимаю, в чем разница между этими сценариями?
Наконец, немного общего вопроса, но есть ли что-то явно неправильное в этом фрагменте кода или в моих предположениях выше?
Спасибо.
РЕДАКТИРОВАТЬ: В ответ на мое использование ObjectDisposedException для прерывания цикла:
Вот как выглядит мой метод «Стоп» (из того же класса, что и выше):
public void Stop()
{
this.tcp.Close();
}
Это приводит к тому, что ожидающий 'ReadAsync' за исключением ObjectDisposedException. AFAIK нет другого способа прервать это. Изменение этого на:
public void Stop()
{
this.tcp.Client.Shutdown(SocketShutdown.Both);
}
На самом деле ничего не делает с ожидающим вызовом, он просто продолжает ждать.