Code development platform for open source projects from the European Union institutions

Skip to content
Snippets Groups Projects
Commit d9cd1bec authored by Markus Quaritsch's avatar Markus Quaritsch
Browse files

refactoring: VectoRuns now use background worker, driving cycle has progress...

refactoring: VectoRuns now use background worker, driving cycle has progress indicator, vectorun updates progress
parent eddf29d9
No related branches found
No related tags found
No related merge requests found
......@@ -33,5 +33,6 @@ namespace TUGraz.VectoCore.Models.Connector.Ports
IResponse Request(Second absTime, Second dt);
IResponse Initialize();
double Progress { get; }
}
}
\ No newline at end of file
using System.ComponentModel;
namespace TUGraz.VectoCore.Models.Simulation
{
/// <summary>
......@@ -8,7 +10,7 @@ namespace TUGraz.VectoCore.Models.Simulation
/// <summary>
/// Run the simulation.
/// </summary>
void Run();
void Run(BackgroundWorker worker = null);
string Name { get; }
......
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using TUGraz.VectoCore.Models.Simulation.Data;
......@@ -14,7 +17,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
/// </summary>
public class JobContainer : LoggingObject
{
private readonly List<IVectoRun> _runs = new List<IVectoRun>();
internal readonly List<JobEntry> Runs = new List<JobEntry>();
private readonly SummaryFileWriter _sumWriter;
private static int _jobNumber;
......@@ -31,32 +34,132 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
public void AddRun(IVectoRun run)
{
_jobNumber++;
_runs.Add(run);
Runs.Add(new JobEntry() {
Run = run,
Container = this,
});
}
public void AddRuns(IEnumerable<IVectoRun> runs)
{
_jobNumber++;
_runs.AddRange(runs);
//Runs.AddRange(runs);
foreach (var run in runs) {
Runs.Add(new JobEntry() {
Run = run,
Container = this,
});
}
}
public void AddRuns(SimulatorFactory factory)
{
factory.SumWriter = _sumWriter;
factory.JobNumber = _jobNumber++;
_runs.AddRange(factory.SimulationRuns());
AddRuns(factory.SimulationRuns());
}
/// <summary>
/// Execute all runs, waits until finished.
/// </summary>
public void Execute()
public void Execute(bool multithreaded = true)
{
Log.Info("VectoRun started running. Executing Runs.");
Task.WaitAll(_runs.Select(r => Task.Factory.StartNew(r.Run)).ToArray());
foreach (var job in Runs) {
job.Worker = new BackgroundWorker() {
WorkerSupportsCancellation = true,
WorkerReportsProgress = true,
};
job.Worker.DoWork += job.DoWork;
job.Worker.ProgressChanged += job.ProgressChanged;
job.Worker.RunWorkerCompleted += job.RunWorkerCompleted;
if (multithreaded) {
job.Started = true;
job.Worker.RunWorkerAsync();
}
}
if (!multithreaded) {
var entry = Runs.First();
entry.Started = true;
entry.Worker.RunWorkerAsync();
}
//Task.WaitAll(_runs.Select(r => Task.Factory.StartNew(r.Run)).ToArray());
_sumWriter.Finish();
}
public void Cancel()
{
foreach (var job in Runs) {
if (job.Worker != null && job.Worker.WorkerSupportsCancellation) {
job.Worker.CancelAsync();
}
}
}
private static AutoResetEvent resetEvent = new AutoResetEvent(false);
public void WaitFinished()
{
resetEvent.WaitOne();
}
private void JobCompleted(JobEntry jobEntry)
{
var next = Runs.FirstOrDefault(x => x.Started == false);
if (next != null) {
next.Started = true;
next.Worker.RunWorkerAsync();
}
if (Runs.Count(x => x.Done == true) == Runs.Count()) {
_sumWriter.Finish();
resetEvent.Set();
}
}
public Dictionary<string, double> GetProgress()
{
return Runs.ToDictionary(jobEntry => jobEntry.Run.Name, jobEntry => jobEntry.Progress);
}
public bool AllCompleted
{
get { return (Runs.Count(x => x.Done == true) == Runs.Count()); }
}
internal class JobEntry
{
public IVectoRun Run;
public JobContainer Container;
public double Progress;
public bool Done;
public bool Started;
public bool Success;
public bool Canceled;
public BackgroundWorker Worker;
public void DoWork(object sender, DoWorkEventArgs e)
{
var worker = sender as BackgroundWorker;
Run.Run(worker);
if (worker != null && worker.CancellationPending) {
e.Cancel = true;
Canceled = true;
}
Success = Run.FinishedWithoutErrors;
Done = true;
Container.JobCompleted(this);
}
public void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {}
public void ProgressChanged(object sender, ProgressChangedEventArgs e)
{
Progress = e.ProgressPercentage / 1000.0;
}
}
}
}
\ No newline at end of file
using System;
using System.ComponentModel;
using TUGraz.VectoCore.Exceptions;
using TUGraz.VectoCore.Models.Connector.Ports;
using TUGraz.VectoCore.Models.Connector.Ports.Impl;
......@@ -37,7 +38,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
}
public void Run()
public void Run(BackgroundWorker worker = null)
{
Log.Info("VectoJob started running.");
......@@ -50,6 +51,14 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
Container.CommitSimulationStep(AbsTime, dt);
AbsTime += dt;
}
if (worker != null) {
worker.ReportProgress((int)(CyclePort.Progress * 1000));
if (worker.CancellationPending) {
Log.Info("Background Task canceled!");
Container.FinishSimulation();
return;
}
}
} while (response is ResponseSuccess);
} catch (VectoSimulationException vse) {
Log.Error("SIMULATION RUN ABORTED! ========================");
......
......@@ -224,6 +224,17 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
CycleIntervalIterator.LeftSample.RoadGradient);
}
public double Progress
{
get
{
return Data.Entries.Count > 0
? ((CurrentState.Distance - Data.Entries.First().Distance) /
(Data.Entries.Last().Distance - Data.Entries.First().Distance)).Value()
: 0;
}
}
public Meter CycleStartDistance
{
get { return Data.Entries.Count > 0 ? Data.Entries.First().Distance : 0.SI<Meter>(); }
......
......@@ -75,6 +75,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
return NextComponent.Initialize(Data.Entries[index].EngineTorque, Data.Entries[index].EngineSpeed);
}
public double Progress
{
get { throw new NotImplementedException(); }
}
public Meter StartDistance
{
get { throw new NotImplementedException(); }
......
......@@ -69,6 +69,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
throw new NotImplementedException();
}
public double Progress
{
get { throw new NotImplementedException(); }
}
public Meter StartDistance
{
get { return 0.SI<Meter>(); }
......
......@@ -131,8 +131,8 @@ namespace TUGraz.VectoCore.Tests.Integration
jobContainer.Execute();
foreach (var run in jobContainer._runs) {
Assert.IsTrue(run.FinishedWithoutErrors);
foreach (var run in jobContainer.Runs) {
Assert.IsTrue(run.Run.FinishedWithoutErrors);
}
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment