超时从 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;
}
目前我正在使用以下实用程序扩展来读取具有指定超时的 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;
}