Files
MPF/MPF.Library/Data/ProcessingQueue.cs

82 lines
2.3 KiB
C#
Raw Normal View History

2021-03-29 10:23:34 -07:00
using System;
using System.Collections.Concurrent;
using System.Threading;
2021-03-29 10:23:34 -07:00
using System.Threading.Tasks;
2021-03-29 11:55:29 -07:00
namespace MPF.Data
2021-03-29 10:23:34 -07:00
{
2021-03-29 10:50:43 -07:00
public class ProcessingQueue<T> : IDisposable
2021-03-29 10:23:34 -07:00
{
/// <summary>
/// Internal queue to hold data to process
/// </summary>
private readonly ConcurrentQueue<T> InternalQueue;
/// <summary>
/// Custom processing step for dequeued data
/// </summary>
private readonly Action<T> CustomProcessing;
2021-03-29 10:50:43 -07:00
/// <summary>
/// Internal processing task for dequeueing
/// </summary>
private readonly Task ProcessingTask;
/// <summary>
/// Cancellation method for the processing task
/// </summary>
private readonly CancellationTokenSource TokenSource;
2021-03-29 10:23:34 -07:00
public ProcessingQueue(Action<T> customProcessing)
{
this.InternalQueue = new ConcurrentQueue<T>();
this.CustomProcessing = customProcessing;
this.TokenSource = new CancellationTokenSource();
this.ProcessingTask = Task.Run(() => ProcessQueue(), this.TokenSource.Token);
2021-03-29 10:50:43 -07:00
}
/// <summary>
/// Dispose the current instance
/// </summary>
public void Dispose()
{
this.TokenSource.Cancel();
while (!this.ProcessingTask.IsCompleted) ;
2021-03-29 10:50:43 -07:00
this.ProcessingTask.Dispose();
}
/// <summary>
/// Enqueue a new item for processing
/// </summary>
/// <param name="item"></param>
public void Enqueue(T item)
{
this.InternalQueue.Enqueue(item);
2021-03-29 10:23:34 -07:00
}
/// <summary>
/// Process
/// </summary>
private void ProcessQueue()
{
while (true)
{
// If cancellation was requested, just do it
if (this.TokenSource.IsCancellationRequested)
break;
2021-03-29 10:23:34 -07:00
// Nothing in the queue means we get to idle
if (this.InternalQueue.Count == 0)
2021-03-29 10:23:34 -07:00
continue;
// Get the next item from the queue
if (!this.InternalQueue.TryDequeue(out T nextItem))
2021-03-29 10:23:34 -07:00
continue;
// Invoke the lambda, if possible
this.CustomProcessing?.Invoke(nextItem);
}
}
}
}