Implement a dual-Buffer Queue (2) and a dual-Buffer Queue
The previous article (http://www.cnblogs.com/cqgis/p/6403262.html) implements an example of a dual Buffer Queue, we write the consumer method directly into the team instance, in order to achieve better reuse, this article shares an encapsulated generic class
/// <Summary> /// Double Buffer Queue /// </summary> /// <typeparam name = "T"> </typeparam> public class DoubleBufferedQueue <T>: IDisposable {private readonly int _ millisecond; /// <summary> ///// </summary> private readonly Queue <T> _ queue1 = new Queue <T> (); private readonly Queue <T> _ queue2 = new Queue <T> (); private readonly ManualResetEvent _ equeueLock = new ManualResetEvent (true); private readonly ManualRe SetEvent _ detail = new ManualResetEvent (false); private readonly AutoResetEvent _ autoReset = new AutoResetEvent (true); private volatile Queue <T> _ currentQueue; private readonly BackgroundWorker _ backgroundWorker; /// <summary> /// double-Buffer Queue /// </summary> /// <param name = "millisecond"> after the consumer thread processes a batch, latency required for scheduled interval Operations </param> public DoubleBufferedQueue (int millisecond = 0) {_ millisecond = millisecond; _ CurrentQueue = _ queue1; _ backgroundWorker = new BackgroundWorker (); _ backgroundWorker. doWork + = BackgroundWorker_DoWork; _ backgroundWorker. runWorkerAsync ();} // <summary> // message sender's processing method // </summary> public Action <Queue <T> ConsumerAction {get; set ;} private void BackgroundWorker_DoWork (object sender, DoWorkEventArgs e) {while (true) {var readQueue = this. getDequeue (); ConsumerAction ?. Invoke (readQueue); if (_ millisecond> 0) Thread. sleep (TimeSpan. fromMilliseconds (_ millisecond);} // ReSharper disable once FunctionNeverReturns} public void Equeue (T item, Action <T> action = null) {this. _ dequeuelock. waitOne (); this. _ equeueLock. reset (); _ currentQueue. enqueue (item); action ?. Invoke (item); _ equeueLock. set (); _ autoReset. set ();} private Queue <T> GetDequeue () {this. _ autoReset. waitOne (); // this semaphore is used to ensure that no member enters the queue at the time of this. _ dequeuelock. reset (); // pay attention to the order of the two locks. Otherwise, the deadlock may occur. this. _ equeueLock. waitOne (); var readQueue = _ currentQueue; _ currentQueue = (_ currentQueue = _ queue1 )? _ Queue2: _ queue1; this. _ dequeuelock. Set (); return readQueue;} public void Dispose () {_ dequeuelock. Reset (); ConsumerAction ?. Invoke (_ queue1); ConsumerAction ?. Invoke (_ queue2); _ backgroundWorker ?. Dispose ();}}
Specify the ConsumerAction when calling.