Changeset 11682


Ignore:
Timestamp:
12/14/14 01:02:09 (8 years ago)
Author:
swagner
Message:

#2205: Worked on cancellation

  • added throwing of OperationCanceledException in MessagePort.ReceiveMessage
  • tweaked AlgorithmNode to get rid of exceptions when the algorithm is aborted
Location:
branches/OptimizationNetworks
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/OptimizationNetworks/HeuristicLab.Core/3.3/Networks/MessagePort.cs

    r11577 r11682  
    182182      LastMessage = message;
    183183      OnMessageReceived(message, token);
     184      token.ThrowIfCancellationRequested();
    184185    }
    185186    public event EventHandler<EventArgs<IMessage, CancellationToken>> MessageReceived;
  • branches/OptimizationNetworks/HeuristicLab.Networks/3.3/AlgorithmNode.cs

    r11577 r11682  
    3636  public class AlgorithmNode : Node, IAlgorithmNode {
    3737    private object locker = new object();
    38     private Dictionary<IAlgorithm, AutoResetEvent> waitHandles = new Dictionary<IAlgorithm, AutoResetEvent>();
    39     private Dictionary<IAlgorithm, Exception> exceptions = new Dictionary<IAlgorithm, Exception>();
    4038
    4139    new public PortCollection Ports {
     
    115113        }
    116114        algorithm = (IAlgorithm)Algorithm.Clone(cloner);
    117         waitHandles.Add(algorithm, new AutoResetEvent(false));
    118115      }
    119116
     
    131128      }
    132129
    133       algorithm.StoreAlgorithmInEachRun = false;
    134       algorithm.Prepare(true);
    135       algorithm.ExceptionOccurred += Algorithm_ExceptionOccurred;
    136       algorithm.Stopped += Algorithm_Stopped;
    137 
    138       using (token.Register(() => { algorithm.Stop(); })) {
     130      token.ThrowIfCancellationRequested();
     131
     132      Exception exception = null;
     133      using (var started = new AutoResetEvent(false))
     134      using (var stopped = new AutoResetEvent(false))
     135      using (var ctr = token.Register(() => {
     136        started.WaitOne();
     137        try { algorithm.Stop(); }
     138        catch (InvalidOperationException) {
     139          // NOTE:
     140          // After the algorithm's engine is stopped, all stateful items in the algorithm are cleared before the execution state of the algorithm is set to stopped.
     141          // When algorithm.Stop() is called during that operation, an InvalidOperationException is thrown because Stop is called on the engine but the engine is already stopped.
     142          // This exception can be ignored, as the algorithm will stop immediately after the clearing of its stateful items is finished.
     143        }
     144      })) {
     145        algorithm.StoreAlgorithmInEachRun = false;
     146        algorithm.Prepare(true);
     147        algorithm.ExceptionOccurred += (sender, args) => { exception = args.Value; };
     148        algorithm.Started += (sender, args) => { started.Set(); };
     149        algorithm.Stopped += (sender, args) => { stopped.Set(); };
    139150        algorithm.Start();
    140         waitHandles[algorithm].WaitOne();
    141       }
    142 
    143       lock (locker) {
    144         waitHandles[algorithm].Dispose();
    145         waitHandles.Remove(algorithm);
    146 
    147         Exception ex = null;
    148         if (exceptions.TryGetValue(algorithm, out ex)) {
    149           exceptions.Remove(algorithm);
    150           throw ex;
    151         }
    152       }
     151        stopped.WaitOne();
     152      }
     153
     154      if (exception != null) throw exception;
     155      token.ThrowIfCancellationRequested();
    153156
    154157      // retrieve results
     
    166169    }
    167170
    168     private void Algorithm_ExceptionOccurred(object sender, EventArgs<Exception> e) {
    169       var algorithm = (IAlgorithm)sender;
    170       lock (locker) {
    171         exceptions.Add(algorithm, e.Value);
    172       }
    173       algorithm.Stop();
    174     }
    175     private void Algorithm_Stopped(object sender, EventArgs e) {
    176       lock (locker) {
    177         waitHandles[(IAlgorithm)sender].Set();
    178       }
    179     }
    180 
    181171    public event EventHandler AlgorithmChanged;
    182172    protected virtual void OnAlgorithmChanged() {
Note: See TracChangeset for help on using the changeset viewer.