/// <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); } } }
/// <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); } }
/// <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; } }
/// <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; } }