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); } }
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); } }
public static LaundryStressSimulation CreateSimulation(TimeSpan addOneDamp, TimeSpan removeOneDirt, TimeSpan removeOneDamp, uint dirtyArticles) { DirtyRange.Validate(nameof(dirtyArticles), dirtyArticles); LaundryStressSimulation simulation = null; try { simulation = new LaundryStressSimulation(addOneDamp, removeOneDirt, removeOneDamp, dirtyArticles); simulation.Init(); } catch (StateLogicErrorException logicError) { Console.Error.WriteLineAsync(logicError.ToString()); try { simulation?.Dispose(); } catch (Exception e2) { Console.Error.WriteLineAsync(e2.ToString()); } TerminationHelper.TerminateApplication(logicError.Message, logicError); throw; } catch (Exception e) { Console.Error.WriteLineAsync(e.ToString()); try { simulation?.Dispose(); } catch (Exception e2) { Console.Error.WriteLineAsync(e2.ToString()); } throw; } return(simulation); }
public void StartRobot() { if (_activityFlag.SetFromInitializedToStartingUp()) { _robotThread.Start(_cts.Token); DateTime startTimeOut = TimeStampSource.Now + TheMaxTimeToStart; while (State == RobotState.StartingUp && TimeStampSource.Now <= startTimeOut) { Thread.Sleep(TimeSpan.FromMilliseconds(10)); } if (State == RobotState.StartingUp) { TerminationHelper.TerminateApplication( $"The robot named {RobotName} could not start up within {TheMaxTimeToStart} milliseconds."); } } else { throw new InvalidOperationException("Thread already has been started up."); } }