using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading.Channels;
public static class Program
public static void Main()
const int itemsCount = 1000;
const int loopsCount = 20_000_000;
var unbounded = Channel.CreateUnbounded<object>();
for (int i = 0; i < itemsCount; i++)
unbounded.Writer.TryWrite(new());
var bounded = Channel.CreateBounded<object>(Int32.MaxValue);
for (int i = 0; i < itemsCount; i++)
bounded.Writer.TryWrite(new());
{ var x = unbounded.Reader.Count; }
{ var x = unbounded.Reader.TryPeek(out _); }
{ var x = bounded.Reader.Count; }
{ var x = bounded.Reader.TryPeek(out _); }
Console.WriteLine($"Platform: {RuntimeInformation.FrameworkDescription}");
Console.WriteLine($"Unbounded.Reader.Count: {unbounded.Reader.Count:#,0}");
Console.WriteLine($"Bounded.Reader.Count: {unbounded.Reader.Count:#,0}");
Console.WriteLine($"LoopsCount: {loopsCount:#,0}");
Measure("Unbounded-Count", () =>
for (int i = 0; i < loopsCount; i++)
isEmpty = unbounded.Reader.Count == 0;
Measure("Unbounded-TryPeek", () =>
for (int i = 0; i < loopsCount; i++)
isEmpty = !unbounded.Reader.TryPeek(out _);
Measure("Bounded-Count", () =>
for (int i = 0; i < loopsCount; i++)
isEmpty = bounded.Reader.Count == 0;
Measure("Bounded-TryPeek", () =>
for (int i = 0; i < loopsCount; i++)
isEmpty = !bounded.Reader.TryPeek(out _);
static void Measure(string title, Action action)
var stopwatch = Stopwatch.StartNew();
Console.WriteLine($"{title,-17} Duration: {stopwatch.ElapsedMilliseconds,3:#,0} msec");