Читать из PipeReader с таймаутом - PullRequest
1 голос
/ 09 марта 2020

В настоящее время я использую следующее расширение утилиты для чтения из PipeReader с указанным таймаутом. Время ожидания требуется для правильной реализации Keep-Alive на HTTP-сервере.

internal static async Task<ReadResult?> ReadWithTimeoutAsync(this PipeReader reader, TimeSpan timeout)
{
    ReadResult? result = null;

    var readTask = Task.Run(async () =>
    {
        result = await reader.ReadAsync();
    });

    var success = await Task.WhenAny(readTask, Task.Delay(timeout)) == readTask;

    if (!success || (result == null))
    {
        return null;
    }

    return result;
}

Этот код проблематичен c в двух отношениях, так как он вводит блокировку (в пределах Task.Delay), очень много распределений и поток, который будет обрабатываться процессором.

Есть ли более эффективный способ использования PipeReader с таймаутами чтения?

1 Ответ

2 голосов
/ 09 марта 2020

Мы можем использовать CancellationToken для более эффективной реализации тайм-аута:

using var cancellation = new CancellationTokenSource(timout);

try
{
    Data = (await Reader.ReadAsync(cancellation.Token)).Buffer;
}
catch (OperationCanceledException)
{
    return null;
}
...