是否建议长时间等待 C# Channel.Reader.WaitToReadAsync?

Osa*_*aHQ 5 c# asynchronous async-await

BackgroundService/IHostedService在 ASP.NET API 核心应用程序中有一个Channel,它等待在通道上写入其他内容,以便它可以读取并处理它。将项目写入通道的时间间隔可以是每隔几秒或几分钟。

该服务的生命周期很长(与 API 应用程序的生命周期相同),因此通道也是如此。

// Simplified/Example code
using System.Threading.Channels;
// ...
Channel<object> channel = Channel.CreateUnbounded<object>();

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
    while (await channel.Reader.WaitToReadAsync(stoppingToken))
    {
        while (channel.Reader.TryRead(out string item))
        {
            // Process item
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:

  • 是否建议channel.Reader.WaitToReadAsync()长时间等待?(可能需要几分钟才能将项目写入通道)
  • I/O是否channel.Reader.WaitToReadAsync()受限?(使用时会释放线程吗await?)
  • 使用AutoResetEventand 阻塞线程比使用更好吗await/async?(不会浪费 CPU 周期,因为线程只会进入休眠状态)

我主要担心的是channel.Reader.WaitToReadAsync(),CPU 受限并等待很长一段时间,浪费 CPU 资源,并且最好使用其他方法,例如AutoResetEvent

AAA*_*ddd 6

没关系,你的担心是没有根据的。

WaitToReadAsync实现来自UnboundedChannelReaderUnbounded 通道的实例化,它实现了一个特殊的等待者,当写入者写入时会发出信号。

此外,由于这本质上只是waited因此线程会被重用并创建一个延续,直到等待者收到信号为止。

渠道的实施是尽可能优化和简洁的。这并不是说您不能使用您喜欢的任何其他同步原语来推出自己的同步原语。但是,获得像通道一样流式传输、轻量级、可重用、缓存和强大的实现的机会很小。

简而言之,线程正在返回到线程池,并且不会执行异常的自旋阻塞或轮询。