Free cookie consent management tool by TermsFeed Policy Generator

source: branches/Async/HeuristicLab.Scripting/3.3/ExecutableScript.cs @ 13825

Last change on this file since 13825 was 13218, checked in by jkarder, 9 years ago

#2298: applied some of the changes suggested by mkommend in comment:14:ticket:2298

File size: 4.3 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2015 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.Threading;
24using HeuristicLab.Common;
25using HeuristicLab.Core;
26using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
27
28namespace HeuristicLab.Scripting {
29  [Item("Executable Script", "An executable script.")]
30  [StorableClass]
31  public abstract class ExecutableScript : Script {
32    private Thread scriptThread;
33    private DateTime lastUpdateTime;
34
35    [Storable]
36    private TimeSpan executionTime;
37    public TimeSpan ExecutionTime {
38      get { return executionTime; }
39      protected set {
40        executionTime = value;
41        OnExecutionTimeChanged();
42      }
43    }
44
45    public bool Running { get; protected set; }
46
47    #region Construction & Cloning
48    [StorableConstructor]
49    protected ExecutableScript(bool deserializing) : base(deserializing) { }
50    protected ExecutableScript(ExecutableScript original, Cloner cloner)
51      : base(original, cloner) {
52      executionTime = original.executionTime;
53    }
54    protected ExecutableScript()
55      : base() {
56      executionTime = TimeSpan.Zero;
57    }
58    protected ExecutableScript(string code)
59      : base(code) {
60      executionTime = TimeSpan.Zero;
61    }
62    #endregion
63
64    #region Execution
65    protected abstract void ExecuteCode();
66
67    public virtual void Execute() {
68      if (Running)
69        throw new InvalidOperationException("Script is already running");
70
71      ExecutionTime = TimeSpan.Zero;
72      Exception ex = null;
73      var timer = new System.Timers.Timer(250) { AutoReset = true };
74      timer.Elapsed += timer_Elapsed;
75      try {
76        Running = true;
77        OnScriptExecutionStarted();
78        lastUpdateTime = DateTime.UtcNow;
79        timer.Start();
80        ExecuteCode();
81      } catch (Exception e) {
82        ex = e;
83      } finally {
84        timer.Elapsed -= timer_Elapsed;
85        timer.Stop();
86        timer.Dispose();
87        ExecutionTime += DateTime.UtcNow - lastUpdateTime;
88        Running = false;
89        OnScriptExecutionFinished(ex);
90      }
91    }
92
93    public virtual void ExecuteAsync() {
94      scriptThread = new Thread(() => {
95        try {
96          Execute();
97        } finally {
98          scriptThread = null;
99        }
100      });
101      scriptThread.SetApartmentState(ApartmentState.STA);
102      scriptThread.Start();
103    }
104
105    public virtual void Kill() {
106      if (!Running) return;
107
108      scriptThread.Abort();
109    }
110    #endregion
111
112    private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) {
113      var timer = (System.Timers.Timer)sender;
114      timer.Enabled = false;
115      DateTime now = DateTime.UtcNow;
116      ExecutionTime += now - lastUpdateTime;
117      lastUpdateTime = now;
118      timer.Enabled = true;
119    }
120
121    public event EventHandler ScriptExecutionStarted;
122    protected virtual void OnScriptExecutionStarted() {
123      var handler = ScriptExecutionStarted;
124      if (handler != null) handler(this, EventArgs.Empty);
125    }
126
127    public event EventHandler<EventArgs<Exception>> ScriptExecutionFinished;
128    protected virtual void OnScriptExecutionFinished(Exception e) {
129      var handler = ScriptExecutionFinished;
130      if (handler != null) handler(this, new EventArgs<Exception>(e));
131    }
132
133    public event EventHandler ExecutionTimeChanged;
134    protected virtual void OnExecutionTimeChanged() {
135      var handler = ExecutionTimeChanged;
136      if (handler != null) handler(this, EventArgs.Empty);
137    }
138  }
139}
Note: See TracBrowser for help on using the repository browser.