【发布时间】:2020-06-21 07:19:04
【问题描述】:
目前我正在使用以下实用程序扩展来读取具有指定超时的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 读取超时?
【问题讨论】:
-
你不能只使用
ReadAsync传递一个CancellationToken是超时吗? (即CancelAfter) -
@MarcGravell 哦 - 当然,谢谢。
-
附带说明:如果您尝试实现一个 http 服务器,请注意 Kestrel 的实现非常好,并且很容易挂钩;仅将其用于繁重的工作可能会更容易
-
目标实际上是实现 HTTP 服务器本身(并理解 HTTP/2 之类的协议)。我不时查看 Kestrel 的源代码,看看那里是如何实现的。