ActionQueue.cs
1 namespace OverwatchTranscript 2 { 3 public class ActionQueue 4 { 5 // Using ConcurrentQueue<> here would make this process slower. 6 private readonly object queueLock = new object(); 7 private readonly AutoResetEvent signal = new AutoResetEvent(false); 8 private List<Action> queue = new List<Action>(); 9 private Task queueWorker = null!; 10 private bool stopping = false; 11 12 public void Start() 13 { 14 queueWorker = Task.Run(QueueWorker); 15 } 16 17 public int Count { get; private set; } 18 19 public void StopAndJoin() 20 { 21 stopping = true; 22 queueWorker.Wait(); 23 if (queue.Count > 0) throw new Exception("not all acions handled"); 24 queueWorker.Dispose(); 25 } 26 27 public void Add(Action action) 28 { 29 if (stopping) throw new Exception("queue stopping"); 30 31 lock (queueLock) 32 { 33 queue.Add(action); 34 Count = queue.Count; 35 } 36 signal.Set(); 37 } 38 39 private void QueueWorker() 40 { 41 while (true) 42 { 43 signal.WaitOne(10); 44 45 List<Action> work = null!; 46 lock (queueLock) 47 { 48 work = queue; 49 queue = new List<Action>(); 50 Count = 0; 51 } 52 if (stopping && !work.Any()) return; 53 54 foreach (var action in work) 55 { 56 action(); 57 } 58 } 59 } 60 } 61 }