예제 #1
0
        /// <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");
        }
예제 #2
0
    // 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);