是否建议在C#频道等待.读者是否长时间等待ReadAsync



我在ASP中有一个BackgroundService/IHostedService。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
}
}
}

我的问题是:

  • 是否建议长时间等待channel.Reader.WaitToReadAsync()?(可能需要几分钟才能将项目写入频道(
  • 是否绑定了channel.Reader.WaitToReadAsync()I/O?(使用await时是否释放线程?(
  • 使用AutoResetEvent并阻塞线程比使用await/async更好吗?(没有浪费CPU周期,因为线程将进入睡眠状态(

我主要担心的是channel.Reader.WaitToReadAsync()是CPU绑定的,并且等待它很长一段时间,浪费CPU资源,应该使用AutoResetEvent等其他方法更好

没关系,您的担忧是没有根据的。

WaitToReadAsync实现来自Unbounded通道实例化的UnboundedChannelReader,该通道实现了一个特殊的awaiter,该awaiter在编写器写入时发出信号。

此外,由于本质上只是等待,线程被重用并创建一个延续,直到唤醒被发出信号。

渠道的实施是尽可能优化和简洁的。这并不是说你不能使用你喜欢的任何其他同步原语来滚动你自己的。但是,实现流式排列、轻量级、可重用、缓存和功能强大的通道的可能性很小。

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

最新更新