Index: trunk/sources/HeuristicLab.DistributedEngine/DistributedEngine.cs
===================================================================
--- trunk/sources/HeuristicLab.DistributedEngine/DistributedEngine.cs	(revision 34)
+++ trunk/sources/HeuristicLab.DistributedEngine/DistributedEngine.cs	(revision 35)
@@ -37,4 +37,5 @@
     private List<Guid> runningEngines = new List<Guid>();
     private string serverAddress;
+    private bool cancelRequested;
     public string ServerAddress {
       get { return serverAddress; }
@@ -50,5 +51,4 @@
       }
     }
-
     public override object Clone(IDictionary<Guid, object> clonedObjects) {
       DistributedEngine clone = (DistributedEngine)base.Clone(clonedObjects);
@@ -81,78 +81,83 @@
 
     public override void Abort() {
-      base.Abort();
-      foreach(Guid engineGuid in runningEngines) {
-        server.AbortEngine(engineGuid);
+      lock(runningEngines) {
+        cancelRequested = true;
+        foreach(Guid engineGuid in runningEngines) {
+          server.AbortEngine(engineGuid);
+        }
       }
+    }
+    public override void Reset() {
+      base.Reset();
+      engineOperations.Clear();
+      runningEngines.Clear();
+      cancelRequested = false;
     }
 
     protected override void ProcessNextOperation() {
-      if(runningEngines.Count != 0) {
-        Guid engineGuid = runningEngines[0];
-        byte[] resultXml = server.TryEndExecuteEngine(engineGuid,100);
-        if(resultXml != null) {
-          GZipStream stream = new GZipStream(new MemoryStream(resultXml), CompressionMode.Decompress);
-          ProcessingEngine resultEngine = (ProcessingEngine)PersistenceManager.Load(stream);
-          IScope oldScope = engineOperations[engineGuid].Scope;
-          oldScope.Clear();
-          foreach(IVariable variable in resultEngine.InitialOperation.Scope.Variables) {
-            oldScope.AddVariable(variable);
+      lock(runningEngines) {
+        if(runningEngines.Count == 0 && cancelRequested) {
+          base.Abort();
+          cancelRequested = false;
+          return;
+        }
+        if(runningEngines.Count != 0) {
+          Guid engineGuid = runningEngines[0];
+          byte[] resultXml = server.TryEndExecuteEngine(engineGuid, 100);
+          if(resultXml != null) {
+            GZipStream stream = new GZipStream(new MemoryStream(resultXml), CompressionMode.Decompress);
+            ProcessingEngine resultEngine = (ProcessingEngine)PersistenceManager.Load(stream);
+            IScope oldScope = engineOperations[engineGuid].Scope;
+            oldScope.Clear();
+            foreach(IVariable variable in resultEngine.InitialOperation.Scope.Variables) {
+              oldScope.AddVariable(variable);
+            }
+            foreach(IScope subScope in resultEngine.InitialOperation.Scope.SubScopes) {
+              oldScope.AddSubScope(subScope);
+            }
+            OnOperationExecuted(engineOperations[engineGuid]);
+            if(resultEngine.ExecutionStack.Count != 0) {
+              foreach(IOperation op in resultEngine.ExecutionStack) {
+                myExecutionStack.Push(op);
+              }
+            }
+            runningEngines.Remove(engineGuid);
+            engineOperations.Remove(engineGuid);
           }
-          foreach(IScope subScope in resultEngine.InitialOperation.Scope.SubScopes) {
-            oldScope.AddSubScope(subScope);
+          return;
+        }
+        IOperation operation = myExecutionStack.Pop();
+        if(operation is AtomicOperation) {
+          AtomicOperation atomicOperation = (AtomicOperation)operation;
+          IOperation next = null;
+          try {
+            next = atomicOperation.Operator.Execute(atomicOperation.Scope);
+          } catch(Exception ex) {
+            // push operation on stack again
+            myExecutionStack.Push(atomicOperation);
+            Abort();
+            ThreadPool.QueueUserWorkItem(delegate(object state) { OnExceptionOccurred(ex); });
           }
-          runningEngines.Remove(engineGuid);
-          engineOperations.Remove(engineGuid);
-        }
-
-        if(Canceled) {
-          // write back not finished tasks
-          //CompositeOperation remaining = new CompositeOperation();
-          //remaining.ExecuteInParallel = true;
-          //for(int i = 0; i < list.tasks.Length; i++) {
-          //  if(list.tasks[i].Count > 0) {
-          //    CompositeOperation task = new CompositeOperation();
-          //    while(list.tasks[i].Count > 0)
-          //      task.AddOperation(list.tasks[i].Pop());
-          //    remaining.AddOperation(task);
-          //  }
-          //}
-          //if(remaining.Operations.Count > 0)
-          //  stack.Push(remaining);
-        }
-        return;
-      }
-      IOperation operation = myExecutionStack.Pop();
-      if(operation is AtomicOperation) {
-        AtomicOperation atomicOperation = (AtomicOperation)operation;
-        IOperation next = null;
-        try {
-          next = atomicOperation.Operator.Execute(atomicOperation.Scope);
-        } catch(Exception ex) {
-          // push operation on stack again
-          myExecutionStack.Push(atomicOperation);
-          Abort();
-          ThreadPool.QueueUserWorkItem(delegate(object state) { OnExceptionOccurred(ex); });
-        }
-        if(next != null)
-          myExecutionStack.Push(next);
-        OnOperationExecuted(atomicOperation);
-        if(atomicOperation.Operator.Breakpoint) Abort();
-      } else if(operation is CompositeOperation) {
-        CompositeOperation compositeOperation = (CompositeOperation)operation;
-        if(compositeOperation.ExecuteInParallel) {
-          foreach(AtomicOperation parOperation in compositeOperation.Operations) {
-            ProcessingEngine engine = new ProcessingEngine(OperatorGraph, GlobalScope, parOperation); // OperatorGraph not needed?
-            MemoryStream memStream = new MemoryStream();
-            GZipStream stream = new GZipStream(memStream, CompressionMode.Compress, true);
-            PersistenceManager.Save(engine, stream);
-            stream.Close();
-            Guid currentEngineGuid = server.BeginExecuteEngine(memStream.ToArray());
-            runningEngines.Add(currentEngineGuid);
-            engineOperations[currentEngineGuid] = parOperation;
+          if(next != null)
+            myExecutionStack.Push(next);
+          OnOperationExecuted(atomicOperation);
+          if(atomicOperation.Operator.Breakpoint) Abort();
+        } else if(operation is CompositeOperation) {
+          CompositeOperation compositeOperation = (CompositeOperation)operation;
+          if(compositeOperation.ExecuteInParallel) {
+            foreach(AtomicOperation parOperation in compositeOperation.Operations) {
+              ProcessingEngine engine = new ProcessingEngine(OperatorGraph, GlobalScope, parOperation); // OperatorGraph not needed?
+              MemoryStream memStream = new MemoryStream();
+              GZipStream stream = new GZipStream(memStream, CompressionMode.Compress, true);
+              PersistenceManager.Save(engine, stream);
+              stream.Close();
+              Guid currentEngineGuid = server.BeginExecuteEngine(memStream.ToArray());
+              runningEngines.Add(currentEngineGuid);
+              engineOperations[currentEngineGuid] = parOperation;
+            }
+          } else {
+            for(int i = compositeOperation.Operations.Count - 1; i >= 0; i--)
+              myExecutionStack.Push(compositeOperation.Operations[i]);
           }
-        } else {
-          for(int i = compositeOperation.Operations.Count - 1; i >= 0; i--)
-            myExecutionStack.Push(compositeOperation.Operations[i]);
         }
       }
Index: trunk/sources/HeuristicLab.Grid/ClientForm.cs
===================================================================
--- trunk/sources/HeuristicLab.Grid/ClientForm.cs	(revision 34)
+++ trunk/sources/HeuristicLab.Grid/ClientForm.cs	(revision 35)
@@ -46,4 +46,5 @@
     private ProcessingEngine currentEngine;
     private string clientUrl;
+    private object locker = new object();
 
     public ClientForm() {
@@ -96,27 +97,31 @@
 
     private void fetchOperationTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) {
-      byte[] engineXml;
-      fetchOperationTimer.Stop();
-      if (engineStore.TryTakeEngine(clientUrl, out currentGuid, out engineXml)) {
-        currentEngine = RestoreEngine(engineXml);
-        if (InvokeRequired) { Invoke((MethodInvoker)delegate() { statusTextBox.Text = "Executing engine"; }); } else statusTextBox.Text = "Executing engine";
-        currentEngine.Finished += delegate(object src, EventArgs args) {
-          byte[] resultXml = SaveEngine(currentEngine);
-          engineStore.StoreResult(currentGuid, resultXml);
-          currentGuid = Guid.Empty;
-          currentEngine = null;
-          fetchOperationTimer.Interval = 100;
+      lock(locker) {
+        byte[] engineXml;
+        fetchOperationTimer.Stop();
+        if(engineStore.TryTakeEngine(clientUrl, out currentGuid, out engineXml)) {
+          currentEngine = RestoreEngine(engineXml);
+          if(InvokeRequired) { Invoke((MethodInvoker)delegate() { statusTextBox.Text = "Executing engine"; }); } else statusTextBox.Text = "Executing engine";
+          currentEngine.Finished += delegate(object src, EventArgs args) {
+            byte[] resultXml = SaveEngine(currentEngine);
+            engineStore.StoreResult(currentGuid, resultXml);
+            currentGuid = Guid.Empty;
+            currentEngine = null;
+            fetchOperationTimer.Interval = 100;
+            fetchOperationTimer.Start();
+          };
+          currentEngine.Execute();
+        } else {
+          if(InvokeRequired) { Invoke((MethodInvoker)delegate() { statusTextBox.Text = "Waiting for engine"; }); } else statusTextBox.Text = "Waiting for engine";
+          fetchOperationTimer.Interval = 5000;
           fetchOperationTimer.Start();
-        };
-        currentEngine.Execute();
-      } else {
-        if(InvokeRequired) { Invoke((MethodInvoker)delegate() { statusTextBox.Text = "Waiting for engine"; }); } else statusTextBox.Text = "Waiting for engine";
-        fetchOperationTimer.Interval = 5000;
-        fetchOperationTimer.Start();
+        }
       }
     }
     public void Abort(Guid guid) {
-      if(!IsRunningEngine(guid)) return;
-      currentEngine.Abort();
+      lock(locker) {
+        if(!IsRunningEngine(guid)) return;
+        currentEngine.Abort();
+      }
     }
     public bool IsRunningEngine(Guid guid) {
Index: trunk/sources/HeuristicLab.Grid/EngineStore.cs
===================================================================
--- trunk/sources/HeuristicLab.Grid/EngineStore.cs	(revision 34)
+++ trunk/sources/HeuristicLab.Grid/EngineStore.cs	(revision 35)
@@ -117,5 +117,5 @@
         if(waitHandles.ContainsKey(guid)) {
           ManualResetEvent waitHandle = waitHandles[guid];
-          if(waitHandle.WaitOne(timeout, false)) {
+          if(waitHandle.WaitOne(timeout, true)) {
             waitHandle.Close();
             waitHandles.Remove(guid);
@@ -143,4 +143,5 @@
           waitingEngines.Remove(guid);
           engineList.Remove(guid);
+          waitHandles[guid].Set();
           results.Add(guid, engine);
         }
