Skip to content

Instantly share code, notes, and snippets.

@hodzanassredin
Last active October 9, 2022 12:00
Show Gist options
  • Save hodzanassredin/407baa54ebe99a3b766441cce1a574bc to your computer and use it in GitHub Desktop.
Save hodzanassredin/407baa54ebe99a3b766441cce1a574bc to your computer and use it in GitHub Desktop.
namespace ConsoleApp7
{
public class AsyncMonitor
{
private readonly SemaphoreSlim signal = new SemaphoreSlim(1, 1);
public void Exit()
{
try
{
signal.Release();
}
catch (SemaphoreFullException) { }
}
public async Task Enter(CancellationToken cancellationToken)
{
await signal.WaitAsync(cancellationToken);
}
}
public struct ConditionalContinuation
{
public ConditionalContinuation(TaskCompletionSource continuation, Func<bool> predicate)
{
Continuation = continuation;
Predicate = predicate;
}
public TaskCompletionSource Continuation { get; }
public Func<bool> Predicate { get; }
}
public abstract class ActiveObject
{
private AsyncMonitor monitor = new();
private List<ConditionalContinuation> queue = new();
public virtual Func<CancellationToken, Task>[] Active() => Array.Empty<Func<CancellationToken, Task>>();
public ActiveObject(CancellationToken ct)
{
foreach (var active in Active())
{
Task.Run(() => active(ct));
}
}
public async Task<ExclusiveScope> Exclusive(CancellationToken ct)
{
await monitor.Enter(ct);
return new ExclusiveScope(monitor, queue);
}
public class ExclusiveScope : IDisposable
{
private readonly AsyncMonitor monitor;
private readonly List<ConditionalContinuation> queue;
public ExclusiveScope(AsyncMonitor monitor, List<ConditionalContinuation> queue)
{
this.monitor = monitor;
this.queue = queue;
}
public Task Await(Func<bool> predicate)
{
if (predicate()) return Task.CompletedTask;
var tcs = new TaskCompletionSource();
queue.Add(new ConditionalContinuation(tcs, predicate));
monitor.Exit();
return tcs.Task;
}
public void Dispose()
{
for (int i = 0; i < queue.Count; i++)
{
var condContinuation = queue[i];
if (condContinuation.Predicate())
{
queue.RemoveAt(i);
condContinuation.Continuation.SetResult();
return;
}
}
monitor.Exit();
}
}
}
public class BoundedBuffer<T> : ActiveObject
{
int h = 0;
int n = 0;
T[] B;
public BoundedBuffer(int max, CancellationToken ct) : base(ct)
{
B = new T[max];
}
public async Task<T> Get(CancellationToken ct)
{
using (var region = await this.Exclusive(ct))
{
await region.Await(() => n != 0);//buffer not empty
T x = B[h]; h = (h + 1) % B.Length; n--;
return x;
}
}
public async Task Put(T x, CancellationToken ct)
{
using (var region = await this.Exclusive(ct))
{
await region.Await(() => n != B.Length); /* buffer not full */
B[(h + n) % B.Length] = x; n++;
}
}
public override Func<CancellationToken, Task>[] Active()
{
return new Func<CancellationToken, Task>[] {
async (ct)=>{
while (!ct.IsCancellationRequested)
{
using (var region = await this.Exclusive(ct))
{
Console.WriteLine($"Channel length {n}");
}
//await Task.Delay(1000, ct);
}
}
};
}
}
}
// See https://aka.ms/new-console-template for more information
using ConsoleApp7;
var cts = new CancellationTokenSource();
var ch = new BoundedBuffer<string>(2, cts.Token);
var consumers = Enumerable.Range(0,3).Select(i=> Task.Run(async () =>
{
while (!cts.Token.IsCancellationRequested)
{
try
{
var t = await ch.Get(cts.Token);
Console.WriteLine($"Recieved {t} by {i}");
}
catch (Exception)
{
}
}
})).ToArray();
var producers = Enumerable.Range(0, 3).Select(producer => Task.Run(async () =>
{
var rnd = new Random();
for (int i = 0; i < 100; i++)
{
//await Task.Delay(TimeSpan.FromMilliseconds(rnd.Next(3)));
await ch.Put($"Message {i} from {producer}", cts.Token);
}
})).ToArray();
await Task.WhenAll(producers);
cts.Cancel();
await Task.WhenAll(consumers);
Console.WriteLine("Finished");
@hodzanassredin
Copy link
Author

Output
Channel length 0
Recieved Message 0 from 0 by 0
Recieved Message 0 from 1 by 1
Recieved Message 0 from 2 by 2
Channel length 0
Channel length 0
Recieved Message 1 from 0 by 0
Recieved Message 1 from 2 by 1
Recieved Message 1 from 1 by 2
Channel length 0
Channel length 0
Recieved Message 2 from 2 by 0
Recieved Message 2 from 0 by 1
Recieved Message 2 from 1 by 2
Channel length 0
Recieved Message 3 from 2 by 0
Channel length 0
Recieved Message 3 from 0 by 1
Channel length 0
Recieved Message 3 from 1 by 2
Recieved Message 4 from 2 by 0
Channel length 0
Recieved Message 4 from 0 by 1
Channel length 0
Recieved Message 4 from 1 by 2
Recieved Message 5 from 2 by 0
Channel length 0
Recieved Message 5 from 0 by 1
Recieved Message 5 from 1 by 2
Channel length 0
Recieved Message 6 from 2 by 0
Recieved Message 6 from 0 by 1
Channel length 0
Recieved Message 6 from 1 by 2
Recieved Message 7 from 2 by 0
Channel length 0
Recieved Message 7 from 0 by 1
Recieved Message 7 from 1 by 2
Channel length 0
Recieved Message 8 from 2 by 0
Recieved Message 8 from 0 by 1
Recieved Message 8 from 1 by 2
Channel length 0
Recieved Message 9 from 2 by 0
Recieved Message 9 from 0 by 1
Recieved Message 9 from 1 by 2
Channel length 0
Recieved Message 10 from 2 by 0
Channel length 0
Recieved Message 10 from 0 by 1
Recieved Message 10 from 1 by 2
Channel length 0
Recieved Message 11 from 2 by 0
Recieved Message 11 from 0 by 1
Channel length 0
Recieved Message 11 from 1 by 2
Recieved Message 12 from 2 by 0
Channel length 0
Recieved Message 12 from 0 by 1
Recieved Message 12 from 1 by 2
Channel length 0
Recieved Message 13 from 2 by 0
Recieved Message 13 from 0 by 1
Channel length 0
Recieved Message 13 from 1 by 2
Recieved Message 14 from 2 by 0
Channel length 0
Recieved Message 14 from 0 by 1
Recieved Message 14 from 1 by 2
Channel length 0
Recieved Message 15 from 2 by 0
Recieved Message 15 from 0 by 1
Recieved Message 15 from 1 by 2
Channel length 0
Recieved Message 16 from 2 by 0
Recieved Message 16 from 0 by 1
Recieved Message 16 from 1 by 2
Channel length 0
Recieved Message 17 from 2 by 0
Recieved Message 17 from 0 by 1
Recieved Message 17 from 1 by 2
Channel length 0
Recieved Message 18 from 2 by 0
Recieved Message 18 from 0 by 1
Recieved Message 18 from 1 by 2
Channel length 0
Recieved Message 19 from 2 by 0
Recieved Message 19 from 0 by 1
Channel length 0
Recieved Message 19 from 1 by 2
Recieved Message 20 from 2 by 0
Channel length 0
Recieved Message 20 from 0 by 1
Recieved Message 20 from 1 by 2
Recieved Message 21 from 2 by 0
Channel length 0
Recieved Message 21 from 0 by 1
Recieved Message 21 from 1 by 2
Channel length 0
Recieved Message 22 from 2 by 0
Recieved Message 22 from 0 by 1
Recieved Message 22 from 1 by 2
Channel length 0
Recieved Message 23 from 2 by 0
Recieved Message 23 from 0 by 1
Recieved Message 23 from 1 by 2
Channel length 0
Recieved Message 24 from 2 by 0
Recieved Message 24 from 0 by 1
Channel length 0
Recieved Message 24 from 1 by 2
Recieved Message 25 from 2 by 0
Channel length 0
Recieved Message 25 from 0 by 1
Recieved Message 25 from 1 by 2
Recieved Message 26 from 2 by 0
Channel length 0
Recieved Message 26 from 0 by 1
Recieved Message 26 from 1 by 2
Channel length 0
Recieved Message 27 from 2 by 0
Recieved Message 27 from 0 by 1
Channel length 0
Recieved Message 27 from 1 by 2
Recieved Message 28 from 2 by 0
Channel length 0
Recieved Message 28 from 0 by 1
Recieved Message 28 from 1 by 2
Recieved Message 29 from 2 by 0
Channel length 0
Recieved Message 29 from 0 by 1
Recieved Message 29 from 1 by 2
Channel length 0
Recieved Message 30 from 2 by 0
Recieved Message 30 from 0 by 1
Channel length 0
Recieved Message 30 from 1 by 2
Recieved Message 31 from 2 by 0
Channel length 0
Recieved Message 31 from 0 by 1
Recieved Message 31 from 1 by 2
Channel length 0
Recieved Message 32 from 2 by 0
Recieved Message 32 from 0 by 1
Channel length 0
Recieved Message 32 from 1 by 2
Recieved Message 33 from 2 by 0
Channel length 0
Recieved Message 33 from 0 by 1
Recieved Message 33 from 1 by 2
Recieved Message 34 from 2 by 0
Channel length 0
Recieved Message 34 from 0 by 1
Recieved Message 34 from 1 by 2
Channel length 0
Recieved Message 35 from 2 by 0
Recieved Message 35 from 0 by 1
Recieved Message 35 from 1 by 2
Channel length 0
Recieved Message 36 from 2 by 0
Recieved Message 36 from 0 by 1
Channel length 0
Recieved Message 36 from 1 by 2
Recieved Message 37 from 2 by 0
Channel length 0
Recieved Message 37 from 0 by 1
Recieved Message 37 from 1 by 2
Channel length 0
Recieved Message 38 from 2 by 0
Recieved Message 38 from 0 by 1
Channel length 0
Recieved Message 38 from 1 by 2
Recieved Message 39 from 2 by 0
Channel length 0
Recieved Message 39 from 0 by 1
Recieved Message 39 from 1 by 2
Channel length 0
Recieved Message 40 from 2 by 0
Recieved Message 40 from 0 by 1
Channel length 0
Recieved Message 40 from 1 by 2
Recieved Message 41 from 2 by 0
Channel length 0
Recieved Message 41 from 0 by 1
Recieved Message 41 from 1 by 2
Recieved Message 42 from 2 by 0
Channel length 0
Recieved Message 42 from 0 by 1
Recieved Message 42 from 1 by 2
Channel length 0
Recieved Message 43 from 2 by 0
Recieved Message 43 from 0 by 1
Recieved Message 43 from 1 by 2
Channel length 0
Recieved Message 44 from 2 by 0
Channel length 0
Recieved Message 44 from 0 by 1
Recieved Message 44 from 1 by 2
Channel length 0
Recieved Message 45 from 2 by 0
Recieved Message 45 from 0 by 1
Channel length 0
Recieved Message 45 from 1 by 2
Recieved Message 46 from 2 by 0
Channel length 0
Recieved Message 46 from 0 by 1
Recieved Message 46 from 1 by 2
Recieved Message 47 from 2 by 0
Channel length 0
Recieved Message 47 from 0 by 1
Recieved Message 47 from 1 by 2
Recieved Message 48 from 2 by 0
Channel length 0
Recieved Message 48 from 0 by 1
Recieved Message 48 from 1 by 2
Recieved Message 49 from 2 by 0
Channel length 0
Recieved Message 49 from 0 by 1
Recieved Message 49 from 1 by 2
Channel length 0
Recieved Message 50 from 2 by 0
Recieved Message 50 from 0 by 1
Channel length 0
Recieved Message 50 from 1 by 2
Recieved Message 51 from 2 by 0
Channel length 0
Recieved Message 51 from 0 by 1
Recieved Message 51 from 1 by 2
Channel length 0
Recieved Message 52 from 2 by 0
Recieved Message 52 from 0 by 1
Recieved Message 52 from 1 by 2
Channel length 0
Recieved Message 53 from 2 by 0
Recieved Message 53 from 0 by 1
Channel length 0
Recieved Message 53 from 1 by 2
Recieved Message 54 from 2 by 0
Recieved Message 54 from 0 by 1
Channel length 0
Recieved Message 54 from 1 by 2
Recieved Message 55 from 2 by 0
Channel length 0
Recieved Message 55 from 0 by 1
Recieved Message 55 from 1 by 2
Channel length 0
Recieved Message 56 from 2 by 0
Recieved Message 56 from 0 by 1
Recieved Message 56 from 1 by 2
Channel length 0
Recieved Message 57 from 2 by 0
Recieved Message 57 from 0 by 1
Channel length 0
Recieved Message 57 from 1 by 2
Recieved Message 58 from 2 by 0
Channel length 0
Recieved Message 58 from 0 by 1
Channel length 0
Recieved Message 59 from 2 by 2
Channel length 0
Recieved Message 58 from 1 by 0
Recieved Message 59 from 0 by 1
Recieved Message 60 from 2 by 2
Channel length 0
Recieved Message 59 from 1 by 0
Recieved Message 60 from 0 by 1
Channel length 0
Recieved Message 61 from 2 by 2
Recieved Message 60 from 1 by 0
Channel length 0
Recieved Message 61 from 0 by 1
Recieved Message 62 from 2 by 2
Channel length 0
Recieved Message 61 from 1 by 0
Recieved Message 62 from 0 by 1
Recieved Message 63 from 2 by 2
Channel length 0
Recieved Message 62 from 1 by 0
Recieved Message 63 from 0 by 1
Channel length 0
Recieved Message 64 from 2 by 2
Recieved Message 63 from 1 by 0
Channel length 0
Recieved Message 64 from 0 by 1
Recieved Message 65 from 2 by 2
Channel length 0
Recieved Message 64 from 1 by 0
Recieved Message 65 from 0 by 1
Channel length 0
Recieved Message 66 from 2 by 2
Recieved Message 65 from 1 by 0
Channel length 0
Recieved Message 66 from 0 by 1
Recieved Message 67 from 2 by 2
Channel length 0
Recieved Message 66 from 1 by 0
Recieved Message 67 from 0 by 1
Channel length 0
Recieved Message 68 from 2 by 2
Recieved Message 67 from 1 by 0
Channel length 0
Recieved Message 68 from 0 by 1
Recieved Message 69 from 2 by 2
Recieved Message 68 from 1 by 0
Channel length 0
Recieved Message 69 from 0 by 1
Recieved Message 70 from 2 by 2
Channel length 0
Recieved Message 69 from 1 by 0
Recieved Message 70 from 0 by 1
Channel length 0
Recieved Message 71 from 2 by 2
Recieved Message 70 from 1 by 0
Channel length 0
Recieved Message 71 from 0 by 1
Recieved Message 72 from 2 by 2
Channel length 0
Recieved Message 71 from 1 by 0
Recieved Message 72 from 0 by 1
Channel length 0
Recieved Message 73 from 2 by 2
Channel length 0
Recieved Message 72 from 1 by 0
Recieved Message 73 from 0 by 1
Recieved Message 74 from 2 by 2
Channel length 0
Recieved Message 73 from 1 by 0
Recieved Message 74 from 0 by 1
Recieved Message 75 from 2 by 2
Channel length 0
Recieved Message 74 from 1 by 0
Recieved Message 75 from 0 by 1
Channel length 0
Recieved Message 76 from 2 by 2
Recieved Message 75 from 1 by 0
Channel length 0
Recieved Message 76 from 0 by 1
Recieved Message 77 from 2 by 2
Channel length 0
Recieved Message 76 from 1 by 0
Recieved Message 77 from 0 by 1
Channel length 0
Recieved Message 78 from 2 by 2
Recieved Message 77 from 1 by 0
Channel length 0
Recieved Message 78 from 0 by 1
Recieved Message 79 from 2 by 2
Channel length 0
Recieved Message 78 from 1 by 0
Recieved Message 79 from 0 by 1
Channel length 0
Recieved Message 80 from 2 by 2
Recieved Message 79 from 1 by 0
Channel length 0
Recieved Message 80 from 1 by 1
Recieved Message 80 from 0 by 2
Channel length 0
Recieved Message 81 from 2 by 0
Recieved Message 81 from 0 by 1
Recieved Message 81 from 1 by 2
Channel length 0
Recieved Message 82 from 0 by 0
Recieved Message 82 from 1 by 1
Recieved Message 82 from 2 by 2
Channel length 0
Recieved Message 83 from 0 by 0
Recieved Message 83 from 1 by 1
Recieved Message 83 from 2 by 2
Channel length 0
Recieved Message 84 from 0 by 0
Recieved Message 84 from 1 by 1
Recieved Message 84 from 2 by 2
Channel length 0
Recieved Message 85 from 0 by 0
Recieved Message 85 from 1 by 1
Recieved Message 85 from 2 by 2
Channel length 0
Recieved Message 86 from 0 by 0
Recieved Message 86 from 1 by 1
Recieved Message 86 from 2 by 2
Channel length 0
Recieved Message 87 from 0 by 0
Recieved Message 87 from 1 by 1
Channel length 0
Recieved Message 87 from 2 by 2
Recieved Message 88 from 1 by 1
Channel length 1
Recieved Message 88 from 0 by 0
Channel length 2
Recieved Message 88 from 2 by 2
Recieved Message 89 from 0 by 1
Channel length 2
Recieved Message 89 from 1 by 0
Channel length 2
Recieved Message 89 from 2 by 2
Recieved Message 90 from 0 by 1
Channel length 2
Recieved Message 90 from 1 by 0
Channel length 2
Recieved Message 90 from 2 by 2
Recieved Message 91 from 0 by 1
Channel length 2
Recieved Message 91 from 1 by 0
Recieved Message 91 from 2 by 2
Channel length 2
Recieved Message 92 from 0 by 1
Channel length 2
Recieved Message 92 from 1 by 0
Recieved Message 92 from 2 by 2
Recieved Message 93 from 0 by 1
Channel length 2
Recieved Message 93 from 1 by 0
Channel length 2
Recieved Message 93 from 2 by 2
Recieved Message 94 from 0 by 1
Channel length 2
Recieved Message 94 from 1 by 0
Channel length 2
Recieved Message 94 from 2 by 2
Recieved Message 95 from 0 by 1
Channel length 2
Recieved Message 95 from 1 by 0
Channel length 2
Recieved Message 95 from 2 by 2
Recieved Message 96 from 0 by 1
Recieved Message 96 from 1 by 0
Channel length 2
Channel length 2
Recieved Message 96 from 2 by 2
Recieved Message 97 from 0 by 1
Recieved Message 97 from 1 by 0
Channel length 2
Recieved Message 97 from 2 by 2
Channel length 2
Recieved Message 98 from 1 by 0
Recieved Message 98 from 0 by 1
Channel length 2
Recieved Message 98 from 2 by 2
Recieved Message 99 from 1 by 1
Channel length 1
Recieved Message 99 from 0 by 0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment