Как правильно остановить BinaryReader ReadChar?

Имею такой код

using (var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
using (var reader = new BinaryReader(stream, Encoding.UTF8))
using (cancellationToken.Register(() =>
{
    try { stream.Dispose(); }
    catch { }
}))
{
    while (true)
    {
        cancellationToken.ThrowIfCancellationRequested();

        var messageHeader = ReadMessageHeader(reader);
...
}

private static MessageHeader ReadMessageHeader(BinaryReader streamReader)
{
    var messageHeader = new MessageHeader();

    while (true)
    {
        var line = streamReader.ReadLine();
...
}

public static string ReadLine(this BinaryReader reader)
{
    var result = new StringBuilder();
    bool foundEndOfLine = false;
    char ch;
    while (!foundEndOfLine)
    {
        try
        {
            ch = reader.ReadChar();
...
}

Насколько я понимаю, кусок кода

using (cancellationToken.Register(() =>
{
    try { stream.Dispose(); }
    catch { }
}))

сделан именно для того, чтобы грохнуть поток и закончить чтение, поскольку ReadChar() может находиться в состоянии ожидания, если данные в поток не поступают.

Проблема такого подхода в том, что бросается исключение IOException.

Если платформа NetFramework 4.8, то InnerExseption SocketErrorCode содержит в себе System.Net.Sockets.SocketError.Interrupted Не удается прочитать данные из транспортного соединения: Операция блокирования прервана вызовом WSACancelBlockingCall,

а на NET5 содержит System.Net.Sockets.SocketError.OperationAborted Программа на вашем хост-компьютере разорвала установленное подключение

Как правильно остановить процесс чтения из потока?


Ответы (1 шт):

Автор решения: aepot

То что в .NET 5 изменилось исключение - это нормально. Дело в том, что под капотом HttpClient в Framework 4.x лежит WebRequestHandler, а в .NET Core 3/.NET 5 и новее - SocketsHttpHandler, использующий более современный, с нуля переписанный HTTP движок.

Поэтому исключения в каких-то местах могут быть разные. Просто перепишите код под новые отладочные данные.


Можно конечно WebRequestHandler насильно запихнуть в HttpClient и получать исключения по-старому, но я бы не советовал вам этого делать, так как старый HTTP движок значительно хуже по эффективности, чем новый и много всего не поддерживает в условиях современного интернета.

→ Ссылка