using System; using System.Collections.Concurrent; using System.Threading; namespace ClassicAssist.Misc { public class ThreadQueue : IDisposable { private readonly Action _onAction; private readonly ConcurrentQueue _queue = new ConcurrentQueue(); private readonly EventWaitHandle _wh = new AutoResetEvent( false ); private readonly Thread _workerThread; public ThreadQueue( Action onAction ) { _onAction = onAction; _workerThread = new Thread( ProcessQueue ) { IsBackground = true }; _workerThread.Start(); } public int Count => _queue.Count; public void Dispose() { StopThread(); } public void Clear() { while ( _queue.TryDequeue( out T item ) ) { } } private void ProcessQueue() { while ( _workerThread.IsAlive ) { if ( _queue.TryDequeue( out T queueItem ) ) { if ( queueItem == null ) { return; } _onAction( queueItem ); } else { _wh.WaitOne(); } } } public void Enqueue( T queueItem ) { _queue.Enqueue( queueItem ); try { _wh.Set(); } catch ( ObjectDisposedException ) { } } private void StopThread() { _queue.Enqueue( default ); try { _wh.Set(); } catch ( ObjectDisposedException ) { } _workerThread.Join(); _wh.Close(); } } }