예제 #1
0
        protected virtual void Dry(CancellationTokenPair pair)
        {
            byte unitsToRemove;
            {
                using var lls = LaundryFlags.SpinLock(TimeSpan.FromSeconds(2));
                unitsToRemove = lls.LoadedLaundryItem != LaundryItems.InvalidItem
                    ? lls.LoadedLaundryItem.Dampness
                    : throw new StateLogicErrorException(
                                          "It should not be possible to lack laundry during the wash cycle.");
            }
            byte     unitsToDeduct = unitsToRemove;
            TimeSpan timeRequired  = TimeToDecrementDampnessPerUnit * unitsToRemove;
            double   randomFactor  = RandomNumberSource.Next(1, 11) / 100.0; //introduce randomness factor of 10%, either direction

            Debug.Assert(randomFactor >= 0.0 && randomFactor <= 0.11);
            TimeSpan randomTimeToAddOrSub = timeRequired * randomFactor;

            Debug.Assert(randomTimeToAddOrSub <= timeRequired);
            bool negate = RandomNumberSource.Next(1, 3) == 1;

            randomTimeToAddOrSub = negate ? -randomTimeToAddOrSub : +randomTimeToAddOrSub;
            timeRequired        += randomTimeToAddOrSub;

            Stopwatch sw = null;

            try
            {
                sw = HighPrecisionTimer;
                sw.Restart();
                SimulateWait(pair, timeRequired);
            }
            catch (OperationCanceledException)
            {
                if (sw == null)
                {
                    string log = "For some reason the stopwatch is null.";
                    TerminationHelper.TerminateApplication(log);
                    return;
                }

                TimeSpan elapsed    = sw.Elapsed;
                double   percentage = elapsed >= timeRequired ? 1.0 : elapsed / timeRequired;
                unitsToDeduct = Convert.ToByte(Math.Floor(unitsToRemove * percentage));
                throw;
            }
            finally
            {
                sw?.Reset();
                byte newSetting = (byte)(unitsToRemove - unitsToDeduct);
                Debug.Assert(newSetting <= unitsToRemove);
                using var lls = LaundryFlags.SpinLock(TimeSpan.FromSeconds(2));
                lls.SetDampFactor(newSetting);
                Debug.Assert(lls.LoadedLaundryItem.Dampness <= unitsToRemove);
            }
        }
예제 #2
0
        protected virtual void Soak(CancellationTokenPair token)
        {
            Stopwatch sw = null;

            try
            {
                Debug.WriteLine("Beginning Cleanse Soak");
                byte oldDampness;
                byte newDampness;
                sw = HighPrecisionTimer;
                sw.Reset();
                sw.Start();
                {
                    using LockedLaundryStatus lls =
                              LaundryFlags.SpinLock(token.IndividualToken, TimeSpan.FromSeconds(2));
                    var res = lls.SoakLaundry() ??
                              throw new StateLogicErrorException(
                                        "It is supposed to be impossible to start the machine without laundry in it.");
                    oldDampness = res.OldDampness;
                    newDampness = res.NewDampness;
                }

                Debug.Assert(newDampness >= oldDampness);
                int      dampnessUnitsIncrease = newDampness - oldDampness;
                TimeSpan totalTimeRequired     = TimeToIncrementDampnessPerUnit * dampnessUnitsIncrease;
                TimeSpan timeRemaining         = totalTimeRequired - sw.Elapsed;
                if (timeRemaining > TimeSpan.Zero)
                {
                    SimulateWait(token, timeRemaining, "Beginning soak wait", "Ending soak wait");
                }
            }
            catch (StateLogicErrorException ex)
            {
                Console.Error.WriteLineAsync(ex.ToString());
                Environment.Exit(-1);
            }
            catch (TimeoutException)
            {
                Console.Error.WriteAsync(
                    $"Unable to obtain lock in {nameof(Soak)} method of {nameof(WashTask)} task.");
                throw;
            }
            finally
            {
                sw?.Reset();
                Debug.WriteLine("Ending soak.");
            }
        }
예제 #3
0
        protected virtual void Cleanse(CancellationTokenPair token)
        {
            byte unitsToRemove;
            {
                using var lls = LaundryFlags.SpinLock(TimeSpan.FromSeconds(2));
                unitsToRemove = lls.LoadedLaundryItem != LaundryItems.InvalidItem
                    ? lls.LoadedLaundryItem.SoiledFactor
                    : throw new StateLogicErrorException(
                                          "It should not be possible to lack laundry during the wash cycle.");
            }
            byte      unitsToDeduct = unitsToRemove;
            TimeSpan  timeRequired  = TimeToRemoveOneUnitOfSoil * unitsToRemove;
            Stopwatch sw            = null;

            try
            {
                sw = HighPrecisionTimer;
                sw.Restart();
                if (timeRequired > TimeSpan.Zero)
                {
                    SimulateWait(token, timeRequired, "Beginning cleanse wait.");
                }
            }
            catch (IndividualOperationCancelledException)
            {
                if (sw == null)
                {
                    string log = "For some reason the stopwatch is null.";
                    TerminationHelper.TerminateApplication(log);
                    return;
                }
                TimeSpan elapsed    = sw.Elapsed;
                double   percentage = elapsed >= timeRequired ? 1.0 : elapsed / timeRequired;
                unitsToDeduct = Convert.ToByte(Math.Floor(unitsToRemove * percentage));
                throw;
            }
            finally
            {
                sw?.Reset();
                byte newSetting = (byte)(unitsToRemove - unitsToDeduct);
                Debug.Assert(newSetting <= unitsToRemove);
                using var lls = LaundryFlags.SpinLock(TimeSpan.FromSeconds(2));
                lls.SetSoilFactor(newSetting);
                Debug.Assert(lls.LoadedLaundryItem.SoiledFactor <= unitsToRemove);
            }
        }