void StepRunEntryPoint() { var stepStartTime = new DateTime(); bool suspendRun = true; while (true) { if (suspendRun) { mStartStep.WaitOne(); stepStartTime = DateTime.Now; } else { mStartStep.Reset(); } do { Tick(); }while ((mCurrentInstructionAddress == ProgramCounter) && IsExecuting); suspendRun = !IsRunning || (DateTime.Now - stepStartTime > mRunSpan && !RunDetached); if (suspendRun) { StepPerformed?.Invoke(this, new EventArgs()); } } }
//NOT in UI thread void m_worker_DoWork(object sender, DoWorkEventArgs e) { if (Thread.CurrentThread.Name == null) { Thread.CurrentThread.Name = "Background Simulation Thread"; } if (State != SimulationState.RUNNING_STEP && State != SimulationState.RUNNING) { throw new IllegalStateException("Bad worker state: " + State); } Stopwatch stopwatch = Stopwatch.StartNew(); long reportLastTicks = stopwatch.ElapsedTicks; uint performedSteps = 0; // During debug, this counts IMyExecutable steps as opposed to whole sim steps. var runningAverage = new SimSpeedRunningAverage(minRecordIntervalMillisec: m_speedMeasureIntervalMillisec); SimulationSpeed = 0.0f; while (true) { if (State == SimulationState.RUNNING_STEP) { if (performedSteps >= m_stepsToPerform) { break; } } if (m_worker.CancellationPending) { e.Cancel = true; break; } try { // If the simulation is in between two steps, we allow for model changes, memory block reallocation etc. if (Simulation.IsStepFinished) { Simulation.PerformModelChanges(); Simulation.Reallocate(); } Simulation.PerformStep(State == SimulationState.RUNNING_STEP); ++performedSteps; StepPerformed?.Invoke(this, null); } catch (Exception ex) { MyLog.ERROR.WriteLine("Error occured during simulation: " + ex.Message); m_simulationStoppedException = ex; e.Cancel = true; break; } if (SleepInterval > 0) { Thread.Sleep(SleepInterval); } // Status reporting try { bool doReportThisStep = (State == SimulationState.RUNNING_STEP) && (performedSteps % ReportIntervalSteps == 0); runningAverage.AddTimePoint(SimulationStep, doReportThisStep); var reportIntervalTicks = ReportInterval * Stopwatch.Frequency / 1000; if (doReportThisStep || ((stopwatch.ElapsedTicks - reportLastTicks) >= reportIntervalTicks)) { reportLastTicks = stopwatch.ElapsedTicks; SimulationSpeed = runningAverage.GetItersPerSecond(); if (ProgressChanged != null) { m_lastProgressChangedStep = SimulationStep; ProgressChanged(this, null); } } } catch (Exception ex) { MyLog.WARNING.WriteLine("Error during sim. status reporting: " + ex.Message); // Continue... } } }