예제 #1
0
        /// <summary>
        /// This is the thread that will cause the car to move forward forever
        /// until it finishes its trip or crashes.
        /// </summary>
        /// <param name="ThreadParameter">Any parameter that the thread needs</param>
        protected void Go(object ThreadParameter)
        {
            if (ThreadParameter is Wind windy)
            {
                string ThreadTypeInfo = "";
                switch (windy.Model)
                {
                case ThreadingModel.ManualThreads:
                {
                    ThreadTypeInfo = $"Using new ParameterizedThreadStart thread {Thread.CurrentThread.ManagedThreadId}.";
                }
                break;

                case ThreadingModel.ThreadPoolThreads:
                {
                    ThreadTypeInfo = $"Using ThreadPool thread {Thread.CurrentThread.ManagedThreadId}.";
                }
                break;

                case ThreadingModel.TaskThreads:
                {
                    ThreadTypeInfo = $"Using TaskThreads thread {Thread.CurrentThread.ManagedThreadId}.";
                }
                break;
                }

                Console.WriteLine($"Started to drive car {CarId}, travelling in the {Direction.ToString()} direction, enter intersection every {MilesTillIntersection} miles.\r\nThe wind is coming out of the {windy.WindDirection.ToString()} at {windy.Speed} MPH.{ThreadTypeInfo}");
            }

            // Signal that this thread has started. We don't want to let
            // the cars start the race until ALL cars have started their
            // thread and are ready to go.
            CarIsReadyToGo.Set();

            // If the caller wants ALL cars to start at the same time
            // then all threads will block on the ManualResetEvent.
            // When "Set" is called, ALL threads/cars will start/unblock
            // at the same time
            StartAllCars.WaitOne();

            while ((MilesTravelled < MilesLengthOfTrip) && !CarCrashed)
            {
                MoveOneStep();
            }

            if (CarCrashed)
            {
                Console.WriteLine($"Vehicle {CarId} CRASHED in the intersection after {MilesTravelled} miles of a {MilesLengthOfTrip} mile trip");
            }
            else
            {
                Console.WriteLine($"Vehicle {CarId} successfully completed the {MilesLengthOfTrip} mile trip");

                // Create BOGUS event to have this car removed from list of all cars
                // because it has completed the trip.
                TripCompleted = true;
                CarEnteredOrExitedIntersectionEvent?.Invoke(this);
            }
        }
예제 #2
0
        /// <summary>
        /// Move the car forward one step and tell event listener when the car entered or exited the intersection
        /// </summary>
        protected void MoveOneStep()
        {
            ++MilesTravelled;
            Thread.Sleep(MovementSleep);

            // Check if this car needs a pit stop
            if ((MilesTravelled % MilesTillPitStop) == 0)
            {
                // Try to enter pit area. If there is a spot available
                // then the car can enter, otherwise it MUST wait for
                // one of the cars already in the pit area to get out.
                PitStop.WaitOne();

                // Count the number of times the car has entered the pit area during the race.
                ++NumberOfPitStopMade;

                // Spend some time in the pit area
                Thread.Sleep(MovementSleep);

                // Leave the pit area to allow other cars to enter
                PitStop.Release();
            }

            // Check if we are in intersection
            if ((MilesTravelled % MilesTillIntersection) == 0)
            {
                // Wait at stop sign before entering the intersection
                if (WaitAtStopSign)
                {
                    StopSign.WaitOne();
                }

                InIntersection = true;

                // Indiate this car entered the intersection
                CarEnteredOrExitedIntersectionEvent?.Invoke(this);

                // If the car crashed, then it was already removed from the intersection
                if (!CarCrashed)
                {
                    // Car spends some time in the intersection
                    Thread.Sleep(MovementSleep);

                    InIntersection = false;

                    // Indiate this car left the intersection
                    CarEnteredOrExitedIntersectionEvent?.Invoke(this);
                }

                // Tell any other car waiting at the stop sign
                // that we exited the intersection and it's ok for them
                // to enter.
                if (WaitAtStopSign)
                {
                    StopSign.Set();
                }
            }
        }