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 } }