using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
namespace HT.Cloud.Code
{
///
/// 队列工具类,用于另起线程处理执行类型数据
///
///
public class QueueHelper : IDisposable
{
#region Private Field
///
/// The inner queue.
///
private readonly ConcurrentQueue _innerQueue;
///
/// The deal task.
///
private readonly Task _dealTask;
///
/// The flag for end thread.
///
private bool _endThreadFlag = false;
///
/// The auto reset event.
///
private readonly AutoResetEvent _autoResetEvent = new(true);
#endregion Private Field
#region Public Property
///
/// The deal action.
///
public Action DealAction { get; set; }
#endregion Public Property
#region Constructor
///
/// Initializes a new instance of the QueueHelper`1 class.
///
public QueueHelper()
{
this._innerQueue = new();
this._dealTask = Task.Run(() => this.DealQueue());
}
///
/// Initializes a new instance of the QueueHelper<T> class.
///
/// The deal action.
public QueueHelper(Action DealAction)
{
this.DealAction = DealAction;
this._innerQueue = new();
this._dealTask = Task.Run(() => this.DealQueue());
}
#endregion Constructor
#region Public Method
///
/// Save entity to Queue.
///
/// The entity what will be deal.
public bool Enqueue(T entity)
{
if (!this._endThreadFlag)
{
this._innerQueue.Enqueue(entity);
this._autoResetEvent.Set();
return true;
}
return false;
}
///
/// Disposes current instance, end the deal thread and inner queue.
///
public void Dispose()
{
if (!this._endThreadFlag)
{
this._endThreadFlag = true;
this._innerQueue.Enqueue(default);
this._autoResetEvent.Set();
if (!this._dealTask.IsCompleted)
this._dealTask.Wait();
this._dealTask.Dispose();
this._autoResetEvent.Dispose();
this._autoResetEvent.Close();
}
}
#endregion Public Method
#region Private Method
///
/// Out Queue.
///
/// The init entity.
/// The entity what will be deal.
private bool Dequeue(out T entity)
{
return this._innerQueue.TryDequeue(out entity);
}
///
/// Deal entity in Queue.
///
private void DealQueue()
{
try
{
while (true)
{
if (this.Dequeue(out T entity))
{
if (this._endThreadFlag && Equals(entity, default(T)))
return;
try
{
this.DealAction?.Invoke(entity);
}
catch (Exception ex)
{
LogHelper.Write(ex);
}
}
else
{
this._autoResetEvent.WaitOne();
}
}
}
catch (Exception ex)
{
LogHelper.Write(ex);
}
}
#endregion Private Method
}
}