public static IDisposable ChangeColor(ConsoleColor color) { var current = Console.ForegroundColor; Console.ForegroundColor = color; return(Disposables.Call(() => Console.ForegroundColor = current)); }
public IDisposable Use() { Interlocked.Increment(ref _counter); return(Disposables.Call(() => { var shouldCallAction = false; lock (_mutex) { _counter--; shouldCallAction = (_counter == 0); } if (shouldCallAction) { _action?.Invoke(); } })); }
private void Release() { lock (_mutex) { if (_queue.Any()) { // somebody is awaiting for a token var tcs = _queue.Dequeue(); var token = Disposables.Call(Release); _currentToken = token; tcs.SetResult(token); } else { // nobody is waiting for a token _currentToken = null; } } }
public Task <IDisposable> Lock() { lock (_mutex) { if (_currentToken == null) { // 1. There is no current token, and the lock is free var token = Disposables.Call(Release); _currentToken = token; return(Task.FromResult <IDisposable>(token)); } else { // 2. The lock is busy var tcs = new TaskCompletionSource <IDisposable>(); _queue.Enqueue(tcs); return(tcs.Task); } } }