Created
March 27, 2020 13:52
-
-
Save Ilchert/c122b74e62763afbdd62cd6604abd134 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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