예제 #1
0
        /// <summary>
        /// Runs the simulation on the current thread and waits for the simulation
        /// to complete before returning to caller. Simulation is NOT cloned before
        /// running. Use instance of Runner to get more options for running a
        /// simulation or groups of simulations.
        /// </summary>
        /// <param name="cancelToken">Is cancellation pending?</param>
        public void Run(CancellationTokenSource cancelToken = null)
        {
            IsRunning = true;
            Exception simulationError = null;

            // If the cancelToken is null then give it a default one. This can happen
            // when called from the unit tests.
            if (cancelToken == null)
            {
                cancelToken = new CancellationTokenSource();
            }

            try
            {
                // Invoke our commencing event to let all models know we're about to start.
                Commencing?.Invoke(this, new EventArgs());

                // Begin running the simulation.
                DoCommence?.Invoke(this, new CommenceArgs()
                {
                    CancelToken = cancelToken
                });
            }
            catch (Exception err)
            {
                // Exception occurred. Write error to summary.
                simulationError = new SimulationException("", err, Name, FileName);
                summary?.WriteError(this, simulationError.ToString());

                // Rethrow exception
                throw simulationError;
            }
            finally
            {
                try
                {
                    // Signal that the simulation is complete.
                    Completed?.Invoke(this, new EventArgs());
                    IsRunning = false;
                }
                catch (Exception error)
                {
                    // If an exception was thrown at this point
                    Exception cleanupError = new SimulationException($"Error while performing simulation cleanup", error, Name, FileName);
                    if (simulationError == null)
                    {
                        throw cleanupError;
                    }
                    throw new AggregateException(simulationError, cleanupError);
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Runs the simulation on the current thread and waits for the simulation
        /// to complete before returning to caller. Simulation is NOT cloned before
        /// running. Use instance of Runner to get more options for running a
        /// simulation or groups of simulations.
        /// </summary>
        /// <param name="cancelToken">Is cancellation pending?</param>
        public void Run(CancellationTokenSource cancelToken = null)
        {
            // If the cancelToken is null then give it a default one. This can happen
            // when called from the unit tests.
            if (cancelToken == null)
            {
                cancelToken = new CancellationTokenSource();
            }

            // Remove disabled models.
            RemoveDisabledModels(this);

            // If this simulation was not created from deserialisation then we need
            // to parent all child models correctly and call OnCreated for each model.
            bool hasBeenDeserialised = Children.Count > 0 && Children[0].Parent == this;

            if (!hasBeenDeserialised)
            {
                // Parent all models.
                Apsim.ParentAllChildren(this);

                // Call OnCreated in all models.
                Apsim.ChildrenRecursively(this).ForEach(m => m.OnCreated());
            }

            if (Services == null || Services.Count < 1)
            {
                Services = new List <object>();
                IDataStore storage = Apsim.Find(this, typeof(IDataStore)) as IDataStore;
                if (storage != null)
                {
                    Services.Add(Apsim.Find(this, typeof(IDataStore)));
                }
            }

            var links  = new Links(Services);
            var events = new Events(this);

            try
            {
                // Connect all events.
                events.ConnectEvents();

                // Resolve all links
                links.Resolve(this, true);

                // Invoke our commencing event to let all models know we're about to start.
                Commencing?.Invoke(this, new EventArgs());

                // Begin running the simulation.
                DoCommence?.Invoke(this, new CommenceArgs()
                {
                    CancelToken = cancelToken
                });
            }
            catch (Exception err)
            {
                // Exception occurred. Write error to summary.
                string errorMessage = "ERROR in file: " + FileName + Environment.NewLine +
                                      "Simulation name: " + Name + Environment.NewLine;
                errorMessage += err.ToString();

                summary?.WriteError(this, errorMessage);

                // Rethrow exception
                throw new Exception(errorMessage, err);
            }
            finally
            {
                // Signal that the simulation is complete.
                Completed?.Invoke(this, new EventArgs());

                // Disconnect our events.
                events.DisconnectEvents();

                // Unresolve all links.
                links.Unresolve(this, true);
            }
        }
예제 #3
0
        /// <summary>Called to start the job.</summary>
        /// <param name="cancelToken">The token to check if job has been cancelled</param>
        public void Run(CancellationTokenSource cancelToken)
        {
            if (simulationEngine != null)
            {
                fileName = simulationEngine.FileName;
                Console.Write("File: " + Path.GetFileNameWithoutExtension(fileName) + ", ");
            }
            Console.WriteLine("Simulation " + simulationToRun.Name + " has commenced.");

            // Start timer to record how long it takes to run
            timer = new Stopwatch();
            timer.Start();

            Events events = null;
            Links  links  = null;

            try
            {
                events = new Events(simulationToRun);

                // Remove disabled models from simulation
                foreach (IModel model in Apsim.ChildrenRecursively(simulationToRun))
                {
                    if (!model.Enabled)
                    {
                        model.Parent.Children.Remove(model as Model);
                    }
                }

                // Get an event and links service
                if (simulationEngine != null)
                {
                    links = simulationEngine.Links;
                }
                else
                {
                    links = new Core.Links(Services);
                }

                // Resolve links and events.
                links.Resolve(simulationToRun, allLinks: true);
                events.ConnectEvents();

                simulationToRun.ClearCaches();

                // Send a commence event so the simulation runs
                object[] args         = new object[] { null, new EventArgs() };
                object[] commenceArgs = new object[] { null, new CommenceArgs()
                                                       {
                                                           CancelToken = cancelToken
                                                       } };
                events.Publish("Commencing", args);
                events.Publish("DoCommence", commenceArgs);
            }
            catch (Exception err)
            {
                string errorMessage = "ERROR in file: " + fileName + "\r\n" +
                                      "Simulation name: " + simulationToRun.Name + "\r\n";
                if (err.InnerException == null)
                {
                    errorMessage += err.Message;
                }
                else
                {
                    errorMessage += err.InnerException.Message;
                }

                ISummary summary = Apsim.Find(simulationToRun, typeof(Summary)) as ISummary;
                if (summary != null)
                {
                    summary.WriteError(simulationToRun, errorMessage);
                }

                throw new Exception(errorMessage, err);
            }
            finally
            {
                events.Publish("Completed", new object[] { null, new EventArgs() });

                // Cleanup the simulation
                if (events != null)
                {
                    events.DisconnectEvents();
                }
                links.Unresolve(simulationToRun, allLinks: true);

                timer.Stop();
                Console.WriteLine("File: " + Path.GetFileNameWithoutExtension(fileName) +
                                  ", Simulation " + simulationToRun.Name + " complete. Time: " + timer.Elapsed.TotalSeconds.ToString("0.00 sec"));
                simulationEngine = null;
                simulationToRun  = null;
            }
        }
예제 #4
0
        /// <summary>
        /// Runs the simulation on the current thread and waits for the simulation
        /// to complete before returning to caller. Simulation is NOT cloned before
        /// running. Use instance of Runner to get more options for running a
        /// simulation or groups of simulations.
        /// </summary>
        /// <param name="cancelToken">Is cancellation pending?</param>
        public void Run(CancellationTokenSource cancelToken = null)
        {
            // If the cancelToken is null then give it a default one. This can happen
            // when called from the unit tests.
            if (cancelToken == null)
            {
                cancelToken = new CancellationTokenSource();
            }

            // Remove disabled models.
            RemoveDisabledModels(this);

            // If this simulation was not created from deserialisation then we need
            // to parent all child models correctly and call OnCreated for each model.
            bool hasBeenDeserialised = Children.Count > 0 && Children[0].Parent == this;

            if (!hasBeenDeserialised)
            {
                // Parent all models.
                this.ParentAllDescendants();

                // Call OnCreated in all models.
                foreach (IModel model in FindAllDescendants().ToList())
                {
                    model.OnCreated();
                }
            }

            // Call OnPreLink in all models.
            // Note the ToList(). This is important because some models can
            // add/remove models from the simulations tree in their OnPreLink()
            // method, and FindAllDescendants() is lazy.
            FindAllDescendants().ToList().ForEach(model => model.OnPreLink());

            if (Services == null || Services.Count < 1)
            {
                var simulations = FindAncestor <Simulations>();
                if (simulations != null)
                {
                    Services = simulations.GetServices();
                }
                else
                {
                    Services = new List <object>();
                    IDataStore storage = this.FindInScope <IDataStore>();
                    if (storage != null)
                    {
                        Services.Add(this.FindInScope <IDataStore>());
                    }
                    Services.Add(new ScriptCompiler());
                }
            }

            var links  = new Links(Services);
            var events = new Events(this);

            try
            {
                // Connect all events.
                events.ConnectEvents();

                // Resolve all links
                links.Resolve(this, true);

                IsRunning = true;

                // Invoke our commencing event to let all models know we're about to start.
                Commencing?.Invoke(this, new EventArgs());

                // Begin running the simulation.
                DoCommence?.Invoke(this, new CommenceArgs()
                {
                    CancelToken = cancelToken
                });
            }
            catch (Exception err)
            {
                // Exception occurred. Write error to summary.
                string errorMessage = "ERROR in file: " + FileName + Environment.NewLine +
                                      "Simulation name: " + Name + Environment.NewLine;
                errorMessage += err.ToString();

                summary?.WriteError(this, errorMessage);

                // Rethrow exception
                throw new Exception(errorMessage, err);
            }
            finally
            {
                // Signal that the simulation is complete.
                Completed?.Invoke(this, new EventArgs());

                // Disconnect our events.
                events.DisconnectEvents();

                // Unresolve all links.
                links.Unresolve(this, true);

                IsRunning = false;
            }
        }