Skip to content

Instantly share code, notes, and snippets.

@kunalspathak
Last active March 1, 2021 16:27
Show Gist options
  • Save kunalspathak/c414bb70718f9fc3f057ea1867e3cd2d to your computer and use it in GitHub Desktop.
Save kunalspathak/c414bb70718f9fc3f057ea1867e3cd2d to your computer and use it in GitHub Desktop.
#nullable enable
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Channels;
using System.Threading.Tasks;
using System.Runtime.CompilerServices;
using BenchmarkDotNet.Attributes;
namespace MiniBench
{
public class AsyncWriter
{
static readonly TestChannelWriter<int> channelWriter = new TestChannelWriter<int>(10000);
private sealed class TestChannelWriter<T> : ChannelWriter<T>
{
private readonly int[] datapoints;
private readonly int _max;
private int _count;
private int _index = 0;
public TestChannelWriter(int max)
{
_max = max;
Random _rand = new Random(42);
datapoints = new int[max * 10];
for (int i = 0; i < max * 10; i++)
{
datapoints[i] = _rand.Next(0, 2);
}
}
public override bool TryWrite(T item)
{
// return true if we are under our limit, and add random failures
return datapoints[_index++] == 0 && _count++ < _max;
}
public override ValueTask<bool> WaitToWriteAsync(CancellationToken cancellationToken)
{
if (_count >= _max)
{
return new ValueTask<bool>(Task.FromResult(false));
}
else
{
if (datapoints[_index++] == 0)
{
// introduce a delay
return new ValueTask<bool>(Task.Delay(1).ContinueWith(_ => true));
//int iter = 0;
//int limit = 1000_1000;
//while (iter++ < limit) ;
}
else
{
return new ValueTask<bool>(Task.FromResult(true));
}
}
}
}
[Benchmark]
public async Task AsyncAwait()
{
int count = 0;
try
{
while (true)
{
await channelWriter.WriteAsync(count++);
}
}
catch (ChannelClosedException)
{
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment