Free cookie consent management tool by TermsFeed Policy Generator

source: branches/SimulationCore/HeuristicLab.SimulationCore/3.3/Simulation.cs @ 8767

Last change on this file since 8767 was 7204, checked in by svonolfe, 13 years ago

Refactored solution (#1610)

File size: 5.7 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Linq;
25using System.Text;
26using HeuristicLab.Core;
27using System.Drawing;
28using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
29using HeuristicLab.Common;
30using HeuristicLab.Collections;
31using HeuristicLab.Optimization;
32using System.Threading;
33using System.Threading.Tasks;
34
35namespace HeuristicLab.SimulationCore {
36  [Item("Simulation", "A base class for simulations.")]
37  [StorableClass]
38  public abstract class Simulation: Algorithm, ISimulation, IStorableContent {
39    public string Filename { get; set; }
40       
41    public override Type ProblemType {
42      get { return typeof(IScenario); }
43    }
44
45    [Storable]
46    private ResultCollection results;
47    public override ResultCollection Results {
48      get {
49        return results;
50      }
51    }
52
53    #region Variables for communication between threads
54    private CancellationTokenSource cancellationTokenSource;
55    private bool stopPending;
56    private DateTime lastUpdateTime;
57    #endregion
58
59    [StorableConstructor]
60    protected Simulation(bool deserializing) : base(deserializing) { }
61    protected Simulation()
62      : base() {
63        results = new ResultCollection();
64    }
65    protected Simulation(Simulation original, Cloner cloner)
66      : base(original, cloner) {
67        results = cloner.Clone(original.results) as ResultCollection;
68    }
69
70    public sealed override void Prepare() {
71      base.Prepare();
72      results.Clear();
73      OnPrepared();
74    }
75    protected override void OnPrepared() {
76      base.OnPrepared();
77    }
78
79    private class RunInformation {
80      public CancellationTokenSource CancellationToken { get; set; }
81      public IExecutionContext ExecutionContext { get; set; }
82    }
83
84    public virtual void Start(IExecutionContext executionContext) {
85      base.Start();
86
87      RunInformation runInfo = new RunInformation();
88      cancellationTokenSource = new CancellationTokenSource();
89      runInfo.CancellationToken = cancellationTokenSource;
90      runInfo.ExecutionContext = executionContext;
91      stopPending = false;
92      Task task = Task.Factory.StartNew(Run, runInfo, runInfo.CancellationToken.Token);
93      task.ContinueWith(t => {
94        try {
95          t.Wait();
96        }
97        catch (AggregateException ex) {
98          try {
99            ex.Flatten().Handle(x => x is OperationCanceledException);
100          }
101          catch (AggregateException remaining) {
102            if (remaining.InnerExceptions.Count == 1) OnExceptionOccurred(remaining.InnerExceptions[0]);
103            else OnExceptionOccurred(remaining);
104          }
105        }
106        cancellationTokenSource.Dispose();
107        cancellationTokenSource = null;
108        if (stopPending) OnStopped();
109        else OnPaused();
110      });
111    }
112
113    public override void Start() {
114      Start(null);     
115    }
116    protected override void OnStarted() {
117      base.OnStarted();
118    }
119
120    public override void Pause() {
121      base.Pause();
122      cancellationTokenSource.Cancel();
123    }
124    protected override void OnPaused() {
125      base.OnPaused();
126    }
127
128    public override void Stop() {
129      base.Stop();
130      if (ExecutionState == ExecutionState.Paused) {
131        OnStopped();
132      } else {
133        stopPending = true;
134        cancellationTokenSource.Cancel();
135      }
136    }
137    protected override void OnStopped() {
138      base.OnStopped();
139    }
140
141    protected override void OnExceptionOccurred(Exception exception) {
142      base.OnExceptionOccurred(exception);
143    }
144
145    private void Run(object state) {
146      RunInformation runInfo = (RunInformation)state;
147
148      OnStarted();
149      lastUpdateTime = DateTime.Now;
150      System.Timers.Timer timer = new System.Timers.Timer(250);
151      timer.AutoReset = true;
152      timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
153      timer.Start();
154      try {
155        foreach (IParameter parameter in Parameters) {
156          parameter.ExecutionContext = runInfo.ExecutionContext;
157        }
158
159        Run(runInfo.CancellationToken.Token);
160      }
161      finally {
162        timer.Elapsed -= new System.Timers.ElapsedEventHandler(timer_Elapsed);
163        timer.Stop();
164        ExecutionTime += DateTime.Now - lastUpdateTime;
165
166        foreach (IParameter parameter in Parameters) {
167          parameter.ExecutionContext = null;
168        }
169      }
170      Stop();
171
172      runInfo.CancellationToken.Token.ThrowIfCancellationRequested();
173    }
174    protected abstract void Run(CancellationToken cancellationToken);
175
176    private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) {
177      System.Timers.Timer timer = (System.Timers.Timer)sender;
178      timer.Enabled = false;
179      DateTime now = DateTime.Now;
180      ExecutionTime += now - lastUpdateTime;
181      lastUpdateTime = now;
182      timer.Enabled = true;
183    }
184  }
185}
Note: See TracBrowser for help on using the repository browser.