Producer consumer C # Concurrent Design Based on Asynchronous queue,

Source: Internet
Author: User

Producer consumer C # Concurrent Design Based on Asynchronous queue,

The original code is based on the concurrency design of the concurrent queue version <producer consumer C # Concurrent Design Based on blocking queue> <. net parallel programming-4. implement High-Performance asynchronous queue> modified. The previous articles also detail other concurrent implementation solutions and implementations. Directly to the code:

Public class MyAsyncQueue <T> {// whether the queue is Processing data private int isProcessing; // a thread is Processing data private const int Processing = 1; // no thread processes data private const int UnProcessing = 0; // whether the queue is available private volatile bool enabled = true; // The Consumer thread private Task currentTask; // The Consumer thread processes the event public event Action <T> ProcessItemFunction; // public event EventHandler <EventArgs <Exception> ProcessException; // the concurrent queue private ConcurrentQueu E <T> queue; // number of consumers private int _ internalTaskCount; // stores the consumer queue List <Task> tasks = new List <Task> (); public MyAsyncQueue () {_ internalTaskCount = 3; queue = new ConcurrentQueue <T> (); Start ();} public int Count {get {return queue. count ;}/// enable the listening Thread private void Start () {Thread process_Thread = new Thread (PorcessItem); process_Thread.IsBackground = true; process_Thread.Start ();} // producer produces pub Lic void Enqueue (T items) {if (items = null) {throw new ArgumentException ("items");} queue. enqueue (items); DataAdded () ;}// notify the consumer thread to process private void DataAdded () {if (enabled) {if (! IsProcessingItem () {// enable consumer consumption queue ProcessRangeItem () ;}}// determine whether a thread in the queue is processing private bool IsProcessingItem () {return! (Interlocked. compareExchange (ref isProcessing, Processing, UnProcessing) = 0);} private void ProcessRangeItem () {for (int I = 0; I <_ internalTaskCount; I ++) {currentTask = Task. factory. startNew () => ProcessItemLoop (); tasks. add (currentTask) ;}}// the consumer processes the event private void ProcessItemLoop () {Console. writeLine ("Id of the Task being executed: {0}", Task. currentId); // The queue is empty and the queue is unavailable if (! Enabled & queue. isEmpty) {Interlocked. exchange (ref isProcessing, 0); return;} // whether the number of threads processed is smaller than the current maximum number of tasks // if (Thread. volatileRead (ref runingCore) <= this. maxTaskCount) // {T publishFrame; while (enabled) {if (queue. tryDequeue (out publishFrame) {try {// consumer Processing Event ProcessItemFunction (publishFrame);} catch (Exception ex) {OnProcessException (ex);} else {Console. writeLine ("thread Id {0} failed to get the queue, jump out of the loop", Task. CurrentId); break ;}}} /// <summary> /// scheduled processing thread call function /// mainly monitors the status of threads not being sent and processed when the queue is in progress. /// </summary> private void porcessItem (object state) {int sleepCount = 0; int sleepTime = 1000; while (enabled) {// if the queue is empty, the sleep time is determined based on the number of cycles if (queue. isEmpty) {// The Task consumer has consumed the data in the queue .... cancel consumer thread if (tasks. count = _ internalTaskCount) {Flush ();} if (sleepCount = 0) {sleepTime = 1000;} else if (sleepCount <= 3) {sleepT Ime = 1000*3;} else {sleepTime = 1000*50;} sleepCount ++; Thread. sleep (sleepTime);} else {// determines whether a thread in the queue is processing if (enabled & Interlocked. compareExchange (ref isProcessing, Processing, UnProcessing) = 0) {if (! Queue. isEmpty) {currentTask = Task. factory. startNew (ProcessItemLoop); tasks. add (currentTask);} else {// The queue is empty and Interlocked has been obtained. exchange (ref isProcessing, 0) ;}sleepcount = 0; sleepTime = 1000 ;}}// update and disable the public void Flush () {Stop () consumer (); foreach (var t in tasks) {if (t! = Null) {t. Wait (); Console. WriteLine ("Task completed") ;}// the consumer has not consumed the while (! Queue. isEmpty) {try {T publishFrame; if (queue. tryDequeue (out publishFrame) {ProcessItemFunction (publishFrame) ;}} catch (Exception ex) {OnProcessException (ex) ;}} currentTask = null; tasks. clear ();} public void Stop () {this. enabled = false;} private void OnProcessException (System. exception ex) {var tempException = ProcessException; Interlocked. compareExchange (ref ProcessException, null, Null); if (tempException! = Null) {ProcessException (ex, new EventArgs <Exception> (ex ));}}}

Call code:

Class ComInfo {public int ComId {get; set;} public DateTime Date {get; set ;}} class Program {static MyAsyncQueue <ComInfo> queue = new MyAsyncQueue <ComInfo> (); static void Main (string [] args) {Console. writeLine ("START ======"); queue. processItemFunction + = A; queue. processException + = C; // new EventHandler <EventArgs <Exception> (C); ComInfo info = new ComInfo (); for (int I = 1; I <50; I ++) {Task. factory. startNew (param) =>{ info = new ComInfo (); info. comId = int. parse (param. toString (); info. date = DateTime. now. date; queue. enqueue (info) ;}, I) ;} Console. writeLine ("End ======"); Console. readKey ();} static void A (ComInfo info) {Console. writeLine (info. comId + "=" + queue. count);} static void C (object ex, EventArgs <Exception> args) {Console. writeLine ("error ");}}

The concurrent series should be finished in this way. You can sort it back into a directory and check it easily.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.