/ Framework / OverwatchTranscript / ActionQueue.cs
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  }