using System; using System.Collections.Generic; using System.Linq; using System.Threading; namespace Domain.Helpers { public class SignalWaiter : IDisposable { public delegate void SignalHandler(); private static readonly SynchronizedCollection<KeyValuePair<string, Semaphore>> Handlers = new SynchronizedCollection<KeyValuePair<string, Semaphore>>(); private readonly KeyValuePair<string, Semaphore> _pair; private readonly CancellationToken _cancellationToken; private readonly TimeSpan _timeout; public static void SendSignal(string key) { Handlers.Where(x => x.Key == key).Select(x => x.Value).ToList().ForEach(x => x.Release()); } public SignalWaiter(string key) : this(key, TimeSpan.FromMinutes(1), new CancellationToken()) { } public SignalWaiter(string key, TimeSpan timeout, CancellationToken cancellationToken) { _pair = new KeyValuePair<string, Semaphore>(key, new Semaphore(0, 1)); _cancellationToken = cancellationToken; _timeout = timeout; Handlers.Add(_pair); } public async Task Wait() { var task1 = Task.Run(() => _cancellationToken.WaitHandle.WaitOne()); var task2 = Task.Run(async () => await _pair.Value.WaitAsync(_timeout)); // _cancellationToken meegeven werkt niet afdoende await Task.WhenAny(task1, task2); } #region IDisposable Support private bool disposedValue = false; protected virtual void Dispose(bool disposing) { if (!disposedValue) { if (disposing) { Handlers.Remove(_pair); _pair.Value.Dispose(); } disposedValue = true; } } public void Dispose() { Dispose(true); } #endregion } }
// example usage var cancellationToken = Request.GetOwinContext()?.Request?.CallCancelled ?? default(CancellationToken); Task.Delay(15000).ContinueWith(x => SignalWaiter.SendSignal("signal1key")); Console.WriteLine($"{DateTime.Now:o} starting"); using (var signalWaiter = new SignalWaiter("signal1key", TimeSpan.FromSeconds(60), cancellationToken)) { await signalWaiter.Wait(); Console.WriteLine($"{DateTime.Now:o} signaled!"); } Console.WriteLine($"{DateTime.Now:o} finished!"); Console.ReadKey();
377610cookie-checkC# signal between threads