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