Опитвам се да се образовам за тънкостите на четенето от 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 изглежда също се задейства при някои обстоятелства. Ако моят отдалечен клиент е C# конзола, тогава затварянето на сокета изглежда прави „A“ случващо се, а затварянето на прозореца на конзолата изглежда прави „B“ случващо се. Не съм сигурен, че разбирам каква е разликата между тези сценарии?
И накрая, малко общ въпрос, но има ли нещо явно нередно с този код или моите горни предположения?
Благодаря.
РЕДАКТИРАНЕ: В отговор на моето използване на ObjectDisposedException за прекъсване на цикъла:
Ето как изглежда моят метод „Стоп“ (от същия клас като по-горе):
public void Stop()
{
this.tcp.Close();
}
Това кара чакащия „ReadAsync“ да се изключи с ObjectDisposedException. AFAIK няма друг начин да се прекъсне това. Промяна на това на:
public void Stop()
{
this.tcp.Client.Shutdown(SocketShutdown.Both);
}
Изглежда всъщност не прави нищо с чакащото повикване, просто продължава да чака.