3y ago · Jun 18, 2023 3:40 PM
If you are still using or raw with manual locks in modern .NET, you should switch to System.Threading.Channels!
Channels are designed for asynchronous producer-consumer pipelines with zero thread blocking and support for backpressure:
CODE
BlockingCollection<T> CODE
ConcurrentQueue<T>Channels are designed for asynchronous producer-consumer pipelines with zero thread blocking and support for backpressure:
CSHARP
using System.Threading.Channels;
public class LogProcessingPipeline
{
// Bounded channel: Holds up to 10,000 items. Drops oldest or blocks producer when full
private readonly Channel<LogMessage> _channel = Channel.CreateBounded<LogMessage>(new BoundedChannelOptions(10_000)
{
SingleWriter = false,
SingleReader = true,
FullMode = BoundedChannelFullMode.Wait
});
// Producer (Multiple threads can call this)
public async ValueTask PublishLogAsync(LogMessage msg, CancellationToken ct = default)
{
await _channel.Writer.WriteAsync(msg, ct);
}
// Consumer (Single dedicated worker thread)
public async Task StartConsumerAsync(CancellationToken ct)
{
ChannelReader<LogMessage> reader = _channel.Reader;
while (await reader.WaitToReadAsync(ct))
{
while (reader.TryRead(out LogMessage item))
{
await WriteToDiskAsync(item);
}
}
}
}
AsyncMaster · Concurrency Geek
Task Parallel Library (TPL), async/await internals, and lock...
Task Parallel Library (TPL), async/await internals, and lock...
The following users thanked AsyncMaster for this post: