/// <summary> /// A simple example of BlockingQueueAsync use /// </summary> /// <param name="args"></param> /// <returns></returns> static async Task Main(string[] args) { BlockingQueueAsync <int> queue = new BlockingQueueAsync <int>(10); ShowCurrentThread("Start Main"); Task <int> taskInt = queue.TakeAsync(); Task t = Task.Run(() => { Task.Delay(5000) .ContinueWith(_ => queue.Put(23)); }); ShowCurrentThread("All Started"); Console.WriteLine(await taskInt); ShowCurrentThread("All Ended"); }
// Test the blocking queue using the synchron//ous interface private static bool TestSyncInterface() { #if (!RUN_CONTINOUSLY) const int RUN_TIME = 10 * 1000; #endif const int EXIT_TIME = 50; const int PRODUCER_THREADS = 10; const int CONSUMER_THREADS = 20; const int QUEUE_SIZE = (PRODUCER_THREADS / 2) + 1; const int MIN_TIMEOUT = 1; const int MAX_TIMEOUT = 50; const int MIN_CANCEL_INTERVAL = 50; const int MAX_CANCEL_INTERVAL = 100; const int MIN_PAUSE_INTERVAL = 10; const int MAX_PAUSE_INTERVAL = 100; const int PRODUCTION_ALIVE = 5000; const int CONSUMER_ALIVE = 5000; Thread[] pthrs = new Thread[PRODUCER_THREADS]; Thread[] cthrs = new Thread[CONSUMER_THREADS]; int[] productions = new int[PRODUCER_THREADS]; int[] productionTimeouts = new int[PRODUCER_THREADS]; int[] productionCancellations = new int[PRODUCER_THREADS]; int[] consumptions = new int[CONSUMER_THREADS]; int[] consumptionTimeouts = new int[CONSUMER_THREADS]; int[] consumptionCancellations = new int[CONSUMER_THREADS]; bool exit = false; BlockingQueueAsync <string> queue = new BlockingQueueAsync <string>(QUEUE_SIZE); // Create and start consumer threads. for (int i = 0; i < CONSUMER_THREADS; i++) { int ctid = i; cthrs[i] = new Thread(() => { Random rnd = new Random(ctid); CancellationTokenSource cts = new CancellationTokenSource(rnd.Next(MIN_CANCEL_INTERVAL, MAX_CANCEL_INTERVAL)); do { do { try { if (queue.Take(rnd.Next(MIN_TIMEOUT, MAX_TIMEOUT), cts.Token) != null) { consumptions[ctid]++; break; } else { consumptionTimeouts[ctid]++; } } catch (OperationCanceledException) { consumptionCancellations[ctid]++; cts.Dispose(); cts = new CancellationTokenSource(rnd.Next(MIN_CANCEL_INTERVAL, MAX_CANCEL_INTERVAL)); } catch (ThreadInterruptedException) { break; } catch (Exception e) { Console.WriteLine($"***Exception: {e.GetType()}: {e.Message}"); break; } } while (true); if (consumptions[ctid] % CONSUMER_ALIVE == 0) { Console.Write($"[#c{ctid:D2}]"); try { Thread.Sleep(rnd.Next(MIN_PAUSE_INTERVAL, MAX_PAUSE_INTERVAL)); } catch (ThreadInterruptedException) { break; } } } while (!Volatile.Read(ref exit)); }); cthrs[i].Priority = ThreadPriority.Highest; cthrs[i].Start(); } // Create and start producer threads. for (int i = 0; i < PRODUCER_THREADS; i++) { int ptid = i; pthrs[i] = new Thread(() => { Random rnd = new Random(ptid); CancellationTokenSource cts = new CancellationTokenSource(rnd.Next(MIN_CANCEL_INTERVAL, MAX_CANCEL_INTERVAL)); do { do { try { if (queue.Put(rnd.Next().ToString(), rnd.Next(MIN_TIMEOUT, MAX_TIMEOUT), cts.Token)) { productions[ptid]++; break; } else { productionTimeouts[ptid]++; } } catch (OperationCanceledException) { productionCancellations[ptid]++; cts.Dispose(); cts = new CancellationTokenSource(rnd.Next(MIN_CANCEL_INTERVAL, MAX_CANCEL_INTERVAL)); } catch (ThreadInterruptedException) { break; } catch (Exception e) { Console.WriteLine($"***Exception: {e.GetType()}: {e.Message}"); break; } } while (true); if (productions[ptid] % PRODUCTION_ALIVE == 0) { Console.Write($"[#p{ptid:D2}]"); try { Thread.Sleep(rnd.Next(MIN_PAUSE_INTERVAL, MAX_PAUSE_INTERVAL)); } catch (ThreadInterruptedException) { break; } } else { Thread.Yield(); } } while (!Volatile.Read(ref exit)); }); pthrs[i].Start(); } // run the test for a while long startTime = Environment.TickCount; do { Thread.Sleep(50); if (Console.KeyAvailable) { Console.Read(); break; } #if RUN_CONTINOUSLY } while (true); #else } while (Environment.TickCount - startTime < RUN_TIME);