Skip to content

Instantly share code, notes, and snippets.

@Ilchert
Created March 27, 2020 13:52
Show Gist options
  • Save Ilchert/c122b74e62763afbdd62cd6604abd134 to your computer and use it in GitHub Desktop.
Save Ilchert/c122b74e62763afbdd62cd6604abd134 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text.Json;
using System.Threading;
using System.Threading.Channels;
using System.Threading.Tasks;
namespace TestApp
{
class Program
{
static async Task Main(string[] args)
{
using (var processor = new GrechaProcessor())
{
processor.Start();
var tasks = new List<Task>(100);
for (int i = 0; i < 10; i++)
{
tasks.Add(Task.Run(async () =>
{
var number = await processor.GetNumber();
Console.WriteLine(number);
}));
}
await Task.WhenAll(tasks);
}
Console.ReadLine();
}
}
class GrechaProcessor : IDisposable
{
private Channel<TaskCompletionSource<int>> channel =
Channel.CreateUnbounded<TaskCompletionSource<int>>(new UnboundedChannelOptions { SingleReader = true });
private CancellationTokenSource cts = new CancellationTokenSource();
private int number = 1;
public void Start()
{
_ = Task.Run(async () =>
{
while (!cts.IsCancellationRequested)
{
var tcs = await channel.Reader.ReadAsync(cts.Token);
if (tcs.Task.IsCompleted)
continue;
tcs.TrySetResult(number++);
await Task.Delay(100, cts.Token); //some workload
}
}, cts.Token);
}
public async Task<int> GetNumber(CancellationToken cancellationToken = default)
{
var tcs = new TaskCompletionSource<int>();
cancellationToken.Register(() => tcs.TrySetCanceled());
await channel.Writer.WriteAsync(tcs, cancellationToken);
return await tcs.Task;
}
public void Dispose()
{
channel.Writer.Complete();
cts.Cancel();
cts.Dispose();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment