System.Threading.Barrier.AddParticipants C# (CSharp) Method

AddParticipants() public method

Notifies the Barrier that there will be additional participants.
is less than /// 0. Adding participants would cause the /// barrier's participant count to exceed . /// The method was invoked from within a post-phase action. /// The current instance has already been /// disposed.
public AddParticipants ( int participantCount ) : long
participantCount int The number of additional participants to add to the /// barrier.
return long
        public long AddParticipants(int participantCount)
        {
            // check dispose
            ThrowIfDisposed();

            if (participantCount < 1)
            {
                throw new ArgumentOutOfRangeException(nameof(participantCount), participantCount,
                    SR.Barrier_AddParticipants_NonPositive_ArgumentOutOfRange);
            }
            else if (participantCount > MAX_PARTICIPANTS) //overflow
            {
                throw new ArgumentOutOfRangeException(nameof(participantCount),
                        SR.Barrier_AddParticipants_Overflow_ArgumentOutOfRange);
            }

            // in case of this is called from the PHA
            if (_actionCallerID != 0 && Environment.CurrentManagedThreadId == _actionCallerID)
            {
                throw new InvalidOperationException(SR.Barrier_InvalidOperation_CalledFromPHA);
            }

            SpinWait spinner = new SpinWait();
            long newPhase = 0;
            while (true)
            {
                int currentTotal = _currentTotalCount;
                int total;
                int current;
                bool sense;
                GetCurrentTotal(currentTotal, out current, out total, out sense);
                if (participantCount + total > MAX_PARTICIPANTS) //overflow
                {
                    throw new ArgumentOutOfRangeException(nameof(participantCount),
                        SR.Barrier_AddParticipants_Overflow_ArgumentOutOfRange);
                }

                if (SetCurrentTotal(currentTotal, current, total + participantCount, sense))
                {
                    // Calculating the first phase for that participant, if the current phase already finished return the nextphase else return the current phase
                    // To know that the current phase is  the sense doesn't match the
                    // phase odd even, so that means it didn't yet change the phase count, so currentPhase +1 is returned, otherwise currentPhase is returned
                    long currPhase = CurrentPhaseNumber;
                    newPhase = (sense != (currPhase % 2 == 0)) ? currPhase + 1 : currPhase;

                    // If this participant is going to join the next phase, which means the postPhaseAction is being running, this participants must wait until this done
                    // and its event is reset.
                    // Without that, if the postPhaseAction takes long time, this means the event ehich the current participant is goint to wait on is still set
                    // (FinishPPhase didn't reset it yet) so it should wait until it reset
                    if (newPhase != currPhase)
                    {
                        // Wait on the opposite event
                        if (sense)
                        {
                            _oddEvent.Wait();
                        }
                        else
                        {
                            _evenEvent.Wait();
                        }
                    }

                    //This else to fix the racing where the current phase has been finished, m_currentPhase has been updated but the events have not been set/reset yet
                    // otherwise when this participant calls SignalAndWait it will wait on a set event however all other participants have not arrived yet.
                    else
                    {
                        if (sense && _evenEvent.IsSet)
                            _evenEvent.Reset();
                        else if (!sense && _oddEvent.IsSet)
                            _oddEvent.Reset();
                    }
                    break;
                }
                spinner.SpinOnce();
            }
            return newPhase;
        }

Usage Example

Beispiel #1
0
        /// <summary>
        /// Test AddParticipants
        /// </summary>
        /// <param name="initialCount">The initial barrier participants count</param>
        /// <param name="participantsToAdd">The aprticipants that will be added</param>
        /// <param name="exceptionType">Type of the exception in case of invalid input, null for valid cases</param>
        /// <returns>Tru if the test succeeded, false otherwise</returns>
        private static bool RunBarrierTest4_AddParticipants(int initialCount, int participantsToAdd, Type exceptionType)
        {
            TestHarness.TestLog("AddParticipants(" + initialCount + "," + participantsToAdd + ")");
            Barrier b = new Barrier(initialCount);
            Exception exception = null;
            try
            {
                if (b.AddParticipants(participantsToAdd) != 0)
                {
                    TestHarness.TestLog("AddParticipants failed, the return phase count is not correct");
                    return false;
                }
                if (b.ParticipantCount != initialCount + participantsToAdd)
                {
                    TestHarness.TestLog("AddParticipants failed, total participant was not increased");
                    return false;
                }

            }
            catch (Exception ex)
            {
                exception = ex;
            }

            if (exception != null && exceptionType == null)
            {
                TestHarness.TestLog("AddParticipants failed, unexpected exception has been thrown.");
                return false;
            }
            if (exception != null && !Type.Equals(exceptionType, exception.GetType()))
            {
                TestHarness.TestLog("AddParticipants failed, exceptions types do not match.");
                return false;
            }
            TestHarness.TestLog("AddParticipants succeeded");
            return true;
        }
All Usage Examples Of System.Threading.Barrier::AddParticipants