Пример #1
0
        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...
                }
            }
        }