RemoveParticipant() public method

Notifies the Barrier that there will be one less participant.
The barrier already has 0 /// participants. /// The method was invoked from within a post-phase action. /// The current instance has already been /// disposed.
public RemoveParticipant ( ) : void
return void
        static void Main(string[] args)
        {
            // create a barrier
            Barrier barrier = new Barrier(2);

            // create a task that will complete
            Task.Factory.StartNew(() => {
                Console.WriteLine("Good task starting phase 0");
                barrier.SignalAndWait();
                Console.WriteLine("Good task starting phase 1");
                barrier.SignalAndWait();
                Console.WriteLine("Good task completed");
            });

            // create a task that will throw an exception
            // with a selective continuation that will reduce the
            // particpant count in the barrier
            Task.Factory.StartNew(() => {
                Console.WriteLine("Bad task 1 throwing exception");
                throw new Exception();

            }).ContinueWith(antecedent => {
                // reduce the particpant count
                Console.WriteLine("Reducing the barrier participant count");
                barrier.RemoveParticipant();
            }, TaskContinuationOptions.OnlyOnFaulted);

            // wait for input before exiting
            Console.WriteLine("Press enter to finish");
            Console.ReadLine();
        }
Example #2
0
        static int[] CalculationInTask(object p)
        {
            var p1 = p as Tuple <int, int, System.Threading.Barrier, List <string> >;

            System.Threading.Barrier barrier = p1.Item3;
            List <string>            data    = p1.Item4;

            int start = p1.Item1 * p1.Item2;
            int end   = start + p1.Item2;

            Console.WriteLine("Задача {0}: раздел от {1} до {2}",
                              Task.CurrentId, start, end);

            int[] charCount = new int[26];
            for (int j = start; j < end; j++)
            {
                char c = data[j][0];
                charCount[c - 97]++;
            }

            Console.WriteLine("Задача {0} завершила вычисление. {1} раз а, {2} раз z",
                              Task.CurrentId, charCount[0], charCount[25]);
            barrier.RemoveParticipant();
            Console.WriteLine("Задача {0} удалена; количество оставшихся участников: {1}",
                              Task.CurrentId, barrier.ParticipantsRemaining);
            return(charCount);
        }
        static void Main(string[] args) {
            var participants = 5;

            // We create a CancellationTokenSource to be able to initiate the cancellation
            var tokenSource = new CancellationTokenSource();
            // We create a barrier object to use it for the rendez-vous points
            var barrier = new Barrier(participants,
                b => {
                    Console.WriteLine("{0} paricipants are at rendez-vous point {1}.",
                                    b.ParticipantCount,
                                    b.CurrentPhaseNumber);
                });

            for (int i = 0; i < participants; i++) {
                var localCopy = i;
                Task.Delay(1000 * localCopy + 1, tokenSource.Token)
                    .ContinueWith(_ => {
                        Console.WriteLine("Task {0} left point A!", localCopy);
                        Thread.Sleep(1000 * localCopy + 1); // Do some "work"
                        if (localCopy % 2 == 0) {
                            Console.WriteLine("Task {0} arrived at point B!", localCopy);
                            barrier.SignalAndWait(tokenSource.Token);
                        }
                        else {
                            Console.WriteLine("Task {0} changed its mind and went back!", localCopy);
                            barrier.RemoveParticipant();
                            return;
                        }
                    }, TaskContinuationOptions.NotOnCanceled)
                    .ContinueWith(_ => {
                        Thread.Sleep(1000 * localCopy + 1);
                        Console.WriteLine("Task {0} arrived at point C!", localCopy);
                        barrier.SignalAndWait(tokenSource.Token);
                    }, TaskContinuationOptions.NotOnCanceled);
            }

            Console.WriteLine("Main thread is waiting for {0} tasks!", barrier.ParticipantsRemaining - 1);
            Console.WriteLine("Press enter to cancel!");
            Console.ReadLine();
            if (barrier.CurrentPhaseNumber < 2) {
                tokenSource.Cancel();
                Console.WriteLine("We canceled the operation!");
            }
            else {
                Console.WriteLine("Too late to cancel!");
            }
            Console.WriteLine("Main thread is done!");
            Console.ReadLine();
        }
        //        static int[] CalculationInTask(object p)
        static int[] CalculationInTask(int jobNumber, int partitionSize, Barrier barrier, IList<string> coll)
        {
            var data = new List<string>(coll);
            int start = jobNumber * partitionSize;
            int end = start + partitionSize;
            Console.WriteLine("Task {0}: partition from {1} to {2}", Task.CurrentId, start, end);
            int[] charCount = new int[26];
            for (int j = start; j < end; j++)
            {
                char c = data[j][0];
                charCount[c - 97]++;
            }
            Console.WriteLine("Calculation completed from task {0}. {1} times a, {2} times z", Task.CurrentId, charCount[0], charCount[25]);

            barrier.RemoveParticipant();
            Console.WriteLine("Task {0} removed from barrier, remaining participants {1}", Task.CurrentId, barrier.ParticipantsRemaining);
            return charCount;
        }
        static void Main(string[] args)
        {
            var participants = 5;

            Barrier barrier = new Barrier(participants + 1, // We add one for the main thread.
                b => {
                    Console.WriteLine("{0} paricipants are at rendez-vous point {1}.",
                                    b.ParticipantCount - 1, // We substract the main thread .
                                    b.CurrentPhaseNumber);
                });

            for (int i = 0; i < participants; i++) {
                var localCopy = i;
                Task.Run(() => {
                    Console.WriteLine("Task {0} left point A!", localCopy);
                    Thread.Sleep(1000 * localCopy + 1); // Do some "work"
                    if (localCopy % 2 == 0) {
                        Console.WriteLine("Task {0} arrived at point B!", localCopy);
                        barrier.SignalAndWait();
                    }
                    else {
                        Console.WriteLine("Task {0} changed its mind and went back!", localCopy);
                        barrier.RemoveParticipant();
                        return;
                    }
                    Thread.Sleep(1000 * (participants - localCopy));
                    Console.WriteLine("Task {0} arrived at point C!", localCopy);
                    barrier.SignalAndWait();
                });
            }

            Console.WriteLine("Main thread is waiting for {0} tasks!", barrier.ParticipantsRemaining - 1);
            barrier.SignalAndWait(); // Waiting at the first phase
            barrier.SignalAndWait(); // Waiting at the second phase
            Console.WriteLine("Main thread is done!");
        }
        private static void CalculationInTask(int jobNumber, int partitionSize, Barrier barrier, IList<string>[] coll, int loops, int[][] results)
        {

            LogBarrierInformation("CalculationInTask started", barrier);

            for (int i = 0; i < loops; i++)
            {
                var data = new List<string>(coll[i]);

                int start = jobNumber * partitionSize;
                int end = start + partitionSize;
                WriteLine($"Task {Task.CurrentId} in loop {i}: partition from {start} to {end}");

                for (int j = start; j < end; j++)
                {
                    char c = data[j][0];
                    results[i][c - 97]++;
                }

                WriteLine($"Calculation completed from task {Task.CurrentId} in loop {i}. " +
                    $"{results[i][0]} times a, {results[i][25]} times z");

                LogBarrierInformation("sending signal and wait for all", barrier);
                barrier.SignalAndWait();
                LogBarrierInformation("waiting completed", barrier);
            }

            barrier.RemoveParticipant();
            LogBarrierInformation("finished task, removed participant", barrier);
        }
Example #7
0
        public void _08_testPutTake_fixed()
        {
            TEST = false;

            // Test that the queue performs correctly under unpredictable concurrent access by using multiple threads to
            // to to perform Put and Take operations over a period of time and that nothing wnet wrong

            MMChannel mmMain = null;

            Console.WriteLine("\nStart of Test Run No. {0} in Test Suite No. {1}\n", ++initTestRunNumber, initTestSuiteNumber);

            try
            {
                int capacity = 500, fileSize = 1000000, viewSize = 1000;
                string QueueName = "_08_testPutTake_fixed";

                // If only performing a small number of trials then GC could impact the timing tests so try and request it beforehand
                // In the case of a small number of trials, hopefully GC won't be required again before the end of the test
                System.GC.Collect();

                // INFO Cannot use the Property (get/set) with an Interlocked -
                // Store the value of the computed checksums here using Interlocked to ensure atomicty
                long putSum = 0;
                // Start and end times of the test run
                long timerStartTime = 0, timerEndTime = 0;

                // test parameters
                // Performance nPairs = 10, capacity = 10, nTrials = 1,000,000 = BlockingCollection = 60s, MMQueue = 254s
                int nPairs = 10, nTrials = initNoOfTrials;

                Random rand = new Random();

                // Create the MMChannel which will instantiate the memory mapped files, mutexes, semaphores etc ...
                mmMain = MMChannel.GetInstance(QueueName, fileSize, viewSize, capacity, TEST, initTestDataStructureType);

                #region Barrier and Barrier Action declaration
                // The barrier will wait for the test runner thread plus a producer and consumer each for the number of pairs
                // Waits for them all to be ready at the start line and again at the finish
                Barrier _barrier = new Barrier(nPairs + 1,
                    actionDelegate =>
                    {
                        // Check to see if the start time variable has been assigned or still = zero
                        // If false then this is the first execution of the barrier action (at the start). Otherwise it is the
                        // second execution 9at the finish)
                        const long zeroFalse_1 = 0; // Not passed by ref so no need to be assignable
                        bool started = Interlocked.Equals(timerStartTime, zeroFalse_1);
                        started = !started;

                        // Store the start time or the end time depending on which execution this is
                        long t = DateTime.Now.Ticks;
                        if (!started)
                        {
                            Interlocked.Exchange(ref timerStartTime, t);
                        }
                        else
                        {
                            Interlocked.Exchange(ref timerEndTime, t);
                        }
                    }
                );
                #endregion Barrier and Barrier Action declaration

                // create pairs of threads to put and take items to/from the queue
                // Including the test runner thread the barriers will wait for nPairs * 2 + 1 ther
                for (int i = 0; i < nPairs; i++)
                {
                    #region Producer Lamda declaration

                    new Thread(
                        new ThreadStart(
                        // Old way - replace lamda expression '() =>' with 'delegate'
                        () =>
                        {
                            try
                            {
                                DateTime centuryBegin = new DateTime(2001, 1, 1);
                                DateTime currentDate = DateTime.Now;

                                int elapsedTicks = (int)(currentDate.Ticks - centuryBegin.Ticks);
                                long result = 0;

                                // Wait at the barrier (start line) until all test threads have been created and are ready to go
                                _barrier.SignalAndWait();

                                // Put the data into the queue as Strings, generating a new random number each time
                                // The consumer will convert back to integers and sum them
                                // The Producer's sum should equal the Consumenr's sum at the end of the test
                                for (int j = nTrials; j > 0; --j)
                                {
                                    // If the RNG is sound then this proves that the data enqueued was dequeued
                                    int r = rand.Next(maxLongRandomSeed);

                                    _08_MMData data;

                                    // Test data string to enqueue and dequeue. Convert to a byte array. This array is a reference type so cannot be directly
                                    // passed to the View Accessor
                                    char[] encodedData = Convert.ToString(r).ToCharArray();
                                    // Store the length of the array for dequeueing later
                                    data.TextLength = encodedData.Length;
                                    // Copy the data to unmanaged memory char by char
                                    for (int k = 0; k < data.TextLength; k++) { unsafe { data.Text[k] = encodedData[k]; } }

                                    mmMain.Put(data);
                                    result += r;

                                }
                                // Atomically store the computed checksum
                                // Comment out for Test 01 as we have already incremented it
                                Interlocked.Add(ref putSum, result);

                                // Wait at the barrier (finish line) until all test threads have been finished
                                _barrier.SignalAndWait();

                            }
                            catch (Exception unexpected)
                            {
                                _barrier.RemoveParticipant();
                                Console.Write("Producer thread terminated after catching an exception from MMChannel 'put()'");
                                Console.Write(unexpected);
                            }
                        }
                    )).Start();

                    #endregion Producer Lamda declaration

                }

                // Wait for all the threads to be ready
                _barrier.SignalAndWait();

                // Wait for all the threads to finish
                _barrier.SignalAndWait();

                // calculate the number of ticks elapsed during the test run
                long elapsedTime = Interlocked.Read(ref timerEndTime) - Interlocked.Read(ref timerStartTime);
                Console.WriteLine("Intermediate Result of _08_testPutTake_fixed() - elapsed time = {0} timer ticks for {1} producer/consumer pairs and {2} Messages",
                    elapsedTime, nPairs, nTrials);

                // Calculate the number of ticks per item enqueued and dequeued - the throughput of the queue
                // A single tick represents one hundred nanoseconds or one ten-millionth of a second.
                // There are 10,000 ticks in a millisecond.
                long ticksPerItem = elapsedTime / (nPairs * (long)nTrials);
                TimeSpan elapsedSpan = new TimeSpan(ticksPerItem);
                double milliSeconds = elapsedSpan.TotalMilliseconds;
                long nanoSeconds = ticksPerItem * 100;
                long throughput = 1000000000 / nanoSeconds;

                // Compares the checksum values computed to determine if the data enqueued was exactly the data dequeued
                Console.WriteLine("1st Result of _08_testPutTake_fixed() = (data enqueued = {0} after {1} trials each by {2} pairs of producers/consumers",
                    Interlocked.Read(ref putSum), nTrials, nPairs);

                Console.WriteLine("2nd Result of _08_testPutTake_fixed() = (Average latency = {0} timer ticks <= Threshold value {1}) = {2}",
                    Interlocked.Read(ref ticksPerItem),
                    AVERAGE_THROUGHPUT_THRESHOLD_TICKS,
                    Interlocked.Read(ref ticksPerItem) <= AVERAGE_THROUGHPUT_THRESHOLD_TICKS);

                Console.WriteLine("_08_testPutTake_fixed Throughput = {0} messages per second ", throughput);

                Console.WriteLine("_08_testPutTake_fixed {0} timer ticks = {1} nanoseconds or {2} milliseconds",
                    ticksPerItem, nanoSeconds, milliSeconds);

                Console.WriteLine("\nEnd of Test Run No. {0} in Test Suite No. {1}\n", initTestRunNumber, initTestSuiteNumber);

            }
            catch (Exception unexpected)
            {
                Console.Write(unexpected);
                throw;
            }
            finally
            {
                // Temporarily delay disposing the queue and its IPC artefacts to allow the consumers to finish draining the queue
                // This will be fixed by waiting in an interrupible loop for the mutex inside the queue and checking if shutdown
                // Thread.Sleep(1000);
                mmMain.Report();
                mmMain.Dispose();
            }
        }
Example #8
0
        private static bool RunBarrierTest7_Bug603035()
        {
            TestHarness.TestLog("*RunBarrierTest7_Bug603035");
            bool failed = false;
            for (int j = 0; j < 100 && !failed; j++)
            {
                Barrier b = new Barrier(0);
               
                Action[] actions = Enumerable.Repeat((Action)(() =>
                {
                    for (int i = 0; i < 400; i++)
                    {
                        try
                        {
                            b.AddParticipant();
                            b.RemoveParticipant();
                        }
                        catch
                        {
                            failed = true;
                            break;
                        }
                    }

                }), 4).ToArray();
                Parallel.Invoke(actions);
                if (b.ParticipantCount != 0)
                    failed = true;
            }

            if (failed)
            {
                TestHarness.TestLog("Bug603035 failed");
                return false;
            }
            TestHarness.TestLog("Bug603035 succeeded");
            return true;

        }