Reputation: 655
I have a BackgroundService/IHostedService
in an ASP.NET API core app with a Channel
, that awaits for something else to write on the channel, so it can read it and process it. The interval of which the items are written to the channel, could be every few seconds or minutes.
This service is long lived (same lifespan as the API app), and therefore the channel as well.
// 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
}
}
}
My questions are:
channel.Reader.WaitToReadAsync()
for long periods? (could be several minutes before an item is written to the channel)channel.Reader.WaitToReadAsync()
I/O bound? (Does it free up the thread when using await
?)AutoResetEvent
and block the thread instead of using await/async
? (No wasted CPU cycles as the thread will simply go to sleep)My primary concern is that channel.Reader.WaitToReadAsync()
is CPU bound and awaiting for it, for long periods of times, wastes CPU resources, and should be better off using other methods like AutoResetEvent
Upvotes: 6
Views: 3594
Reputation: 81563
It's fine, your concerns are unfounded.
WaitToReadAsync
implementation comes from the UnboundedChannelReader
instantiated by Unbounded channel, which implements a special awaiter that is signaled when the writer writes.
Furthermore, since this is essentially just awaited, the thread gets reused and a continuation created until the awaiter is signaled.
The implementation of channels is about as optimised and succinct as you will get. That's not to say you can't roll-your-own using whatever other synchronization primitives you like. But the chances of you getting an implementation as streamed-lined, lightweight, reusable, cached and powerful as channels would be slim.
In short, threads are being returned to the thread pool, and no extraordinary spin-blocking or polling is performed.
Upvotes: 8