超时从 PipeReader 读取

Read from PipeReader with timeout

目前我正在使用以下实用程序扩展来读取具有指定超时的 PipeReader。需要超时才能在 HTTP 服务器中正确实施 Keep-Alive

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;
}

此代码在几个方面存在问题,因为它引入了锁定(在 Task.Delay 内)、大量分配和一个由 CPU 处理的线程。

有没有更有效的方法来使用 PipeReader 读取超时?

我们可以使用 CancellationToken 以更有效的方式实现超时:

using var cancellation = new CancellationTokenSource(timout);

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