Last active
January 17, 2020 16:48
-
-
Save azyobuzin/c4a442fc53d094cff7daefad64a8aa57 to your computer and use it in GitHub Desktop.
This file contains 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.Threading; | |
using System.Threading.Tasks; | |
namespace VeronaLike | |
{ | |
public delegate void WhenCallback<T>(ref T value); | |
public class Cown<T> | |
{ | |
private T _value; | |
private readonly Queue<WhenCallback<T>> _queue = new Queue<WhenCallback<T>>(); | |
private Task _task; | |
public Cown(T value) | |
{ | |
this._value = value; | |
} | |
public void When(WhenCallback<T> callback) | |
{ | |
lock (this._queue) | |
{ | |
this._queue.Enqueue(callback); | |
if (this._task == null) | |
{ | |
this._task = Task.Run(() => | |
{ | |
while (true) | |
{ | |
WhenCallback<T> callback; | |
lock (this._queue) | |
{ | |
if (!this._queue.TryDequeue(out callback)) | |
{ | |
this._task = null; | |
return; | |
} | |
} | |
callback(ref this._value); | |
} | |
}); | |
} | |
} | |
} | |
public ref readonly T Get() => ref this._value; | |
} | |
public struct BankAccount | |
{ | |
public ulong Balance; | |
public static Cown<BankAccount> Create(ulong openingBalance) | |
{ | |
var account = new BankAccount(); | |
account.Balance = openingBalance; | |
return new Cown<BankAccount>(account); | |
} | |
public static void Add(Cown<BankAccount> account, ulong amount) | |
{ | |
account.When((ref BankAccount self) => | |
{ | |
self.Balance += amount; | |
Console.WriteLine("new balance: {0}", self.Balance); | |
}); | |
} | |
} | |
public static class Program | |
{ | |
public static void Example(ulong start) | |
{ | |
var s = BankAccount.Create(start); | |
BankAccount.Add(s, 1); | |
BankAccount.Add(s, 2); | |
BankAccount.Add(s, 3); | |
BankAccount.Add(s, 4); | |
BankAccount.Add(s, 5); | |
BankAccount.Add(s, 6); | |
} | |
public static void Main(string[] args) | |
{ | |
Example(100); | |
Example(200); | |
Example(300); | |
Example(400); | |
Console.WriteLine("done"); | |
// Wait for all tasks | |
Thread.Sleep(1000); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment