我在一个带有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
}
}
}我的问题是:
channel.Reader.WaitToReadAsync()吗?(可能需要几分钟才能将项目写入通道)channel.Reader.WaitToReadAsync() I/O?(当使用await?)AutoResetEvent并阻塞线程,而不是使用await/async?)(没有浪费CPU周期,因为线程只会进入睡眠状态)我主要担心的是,channel.Reader.WaitToReadAsync()是CPU绑定的,并等待它很长时间,浪费CPU资源,最好使用其他方法,如AutoResetEvent。
发布于 2021-01-13 03:10:49
没关系,你的担心是没有根据的。
WaitToReadAsync实现来自由无界通道实例化的UnboundedChannelReader,它实现了一个特殊的服务生,在作者写东西时会发出信号。
此外,由于这个本质上是等待的,所以线程会被重用,并创建一个延续,直到发出信号。
渠道的实现就像你会得到的一样的优化和简洁。这并不是说你不能使用任何你喜欢的同步原语。但是,将实现作为流衬的、轻量级的、可重用的、缓存的和功能强大的通道来实现的可能性微乎其微。
简而言之,线程被返回到线程池,不执行异常的自旋阻塞或轮询。
https://stackoverflow.com/questions/65694956
复制相似问题