Index: branches/Async/HeuristicLab.Optimization/3.3/MetaOptimizers/BatchRun.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization/3.3/MetaOptimizers/BatchRun.cs	(revision 13329)
+++ branches/Async/HeuristicLab.Optimization/3.3/MetaOptimizers/BatchRun.cs	(revision 13349)
@@ -23,4 +23,6 @@
 using System.Collections.Generic;
 using System.Drawing;
+using System.Threading;
+using System.Threading.Tasks;
 using HeuristicLab.Collections;
 using HeuristicLab.Common;
@@ -39,4 +41,6 @@
   [StorableClass]
   public sealed class BatchRun : NamedItem, IOptimizer, IStorableContent {
+    private readonly ManualResetEvent signaler = new ManualResetEvent(true);
+
     public string Filename { get; set; }
 
@@ -244,12 +248,22 @@
     }
     public void Start() {
-      if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused))
-        throw new InvalidOperationException(string.Format("Start not allowed in execution state \"{0}\".", ExecutionState));
-      if (Optimizer == null) return;
-      batchRunAction = BatchRunAction.Start;
-      if (Optimizer.ExecutionState == ExecutionState.Stopped) Optimizer.Prepare();
-      // a race-condition may occur when the optimizer has changed the state by itself in the meantime
-      try { Optimizer.Start(); }
-      catch (InvalidOperationException) { }
+      StartAsync().Wait();
+    }
+    public async Task StartAsync() {
+      await StartAsync(new CancellationToken());
+    }
+    public async Task StartAsync(CancellationToken cancellationToken) {
+      signaler.Reset();
+      await Task.Run(async () => {
+        if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused))
+          throw new InvalidOperationException(string.Format("Start not allowed in execution state \"{0}\".", ExecutionState));
+        if (Optimizer == null) return;
+        batchRunAction = BatchRunAction.Start;
+        if (Optimizer.ExecutionState == ExecutionState.Stopped) Optimizer.Prepare();
+        // a race-condition may occur when the optimizer has changed the state by itself in the meantime
+        try { await Optimizer.StartAsync(cancellationToken); }
+        catch (InvalidOperationException) { }
+        signaler.WaitOne();
+      }, cancellationToken);
     }
     public void Pause() {
@@ -326,4 +340,5 @@
       batchRunAction = BatchRunAction.None;
       ExecutionState = ExecutionState.Paused;
+      signaler.Set();
       EventHandler handler = Paused;
       if (handler != null) handler(this, EventArgs.Empty);
@@ -333,4 +348,5 @@
       batchRunAction = BatchRunAction.None;
       ExecutionState = ExecutionState.Stopped;
+      signaler.Set();
       EventHandler handler = Stopped;
       if (handler != null) handler(this, EventArgs.Empty);
@@ -397,5 +413,5 @@
       else if (batchRunAction == BatchRunAction.Start) {
         Optimizer.Prepare();
-        Optimizer.Start();
+        Optimizer.StartAsync();
       } else if (executionState == ExecutionState.Started) {
         // if the batch run hasn't been started but the inner optimizer was run then pause
Index: branches/Async/HeuristicLab.Optimization/3.3/MetaOptimizers/Experiment.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization/3.3/MetaOptimizers/Experiment.cs	(revision 13329)
+++ branches/Async/HeuristicLab.Optimization/3.3/MetaOptimizers/Experiment.cs	(revision 13349)
@@ -25,4 +25,5 @@
 using System.Linq;
 using System.Threading;
+using System.Threading.Tasks;
 using HeuristicLab.Collections;
 using HeuristicLab.Common;
@@ -38,4 +39,6 @@
   [StorableClass]
   public sealed class Experiment : NamedItem, IOptimizer, IStorableContent {
+    private readonly ManualResetEvent signaler = new ManualResetEvent(true);
+
     public string Filename { get; set; }
 
@@ -186,16 +189,26 @@
     }
     public void Start() {
-      if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused))
-        throw new InvalidOperationException(string.Format("Start not allowed in execution state \"{0}\".", ExecutionState));
-      if (Optimizers.Count == 0) return;
-
-      experimentStarted = true;
-      experimentStopped = false;
-      IOptimizer optimizer = Optimizers.FirstOrDefault(x => (x.ExecutionState == ExecutionState.Prepared) || (x.ExecutionState == ExecutionState.Paused));
-      if (optimizer != null) {
-        // a race-condition may occur when the optimizer has changed the state by itself in the meantime
-        try { optimizer.Start(); }
-        catch (InvalidOperationException) { }
-      }
+      StartAsync().Wait();
+    }
+    public async Task StartAsync() {
+      await StartAsync(new CancellationToken());
+    }
+    public async Task StartAsync(CancellationToken cancellationToken) {
+      signaler.Reset();
+      await Task.Run(async () => {
+        if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused))
+          throw new InvalidOperationException(string.Format("Start not allowed in execution state \"{0}\".", ExecutionState));
+        if (Optimizers.Count == 0) return;
+
+        experimentStarted = true;
+        experimentStopped = false;
+        IOptimizer optimizer = Optimizers.FirstOrDefault(x => (x.ExecutionState == ExecutionState.Prepared) || (x.ExecutionState == ExecutionState.Paused));
+        if (optimizer != null) {
+          // a race-condition may occur when the optimizer has changed the state by itself in the meantime
+          try { await optimizer.StartAsync(cancellationToken); }
+          catch (InvalidOperationException) { }
+        }
+        signaler.WaitOne();
+      }, cancellationToken);
     }
     public void Pause() {
@@ -261,4 +274,5 @@
     private void OnPaused() {
       ExecutionState = ExecutionState.Paused;
+      signaler.Set();
       EventHandler handler = Paused;
       if (handler != null) handler(this, EventArgs.Empty);
@@ -267,4 +281,5 @@
     private void OnStopped() {
       ExecutionState = ExecutionState.Stopped;
+      signaler.Set();
       EventHandler handler = Stopped;
       if (handler != null) handler(this, EventArgs.Empty);
@@ -380,5 +395,5 @@
         } else {
           if (experimentStarted && Optimizers.Any(x => (x.ExecutionState == ExecutionState.Prepared) || (x.ExecutionState == ExecutionState.Paused))) {
-            Optimizers.First(x => (x.ExecutionState == ExecutionState.Prepared) || (x.ExecutionState == ExecutionState.Paused)).Start();
+            Optimizers.First(x => (x.ExecutionState == ExecutionState.Prepared) || (x.ExecutionState == ExecutionState.Paused)).StartAsync();
           } else if (Optimizers.All(x => x.ExecutionState == ExecutionState.Stopped)) OnStopped();
           else if (Optimizers.Any(x => (x.ExecutionState == ExecutionState.Prepared) || (x.ExecutionState == ExecutionState.Paused)) && Optimizers.All(o => o.ExecutionState != ExecutionState.Started)) OnPaused();
Index: branches/Async/HeuristicLab.Optimization/3.3/MetaOptimizers/TimeLimitRun.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization/3.3/MetaOptimizers/TimeLimitRun.cs	(revision 13329)
+++ branches/Async/HeuristicLab.Optimization/3.3/MetaOptimizers/TimeLimitRun.cs	(revision 13349)
@@ -25,4 +25,5 @@
 using System.Drawing;
 using System.Linq;
+using System.Threading;
 using System.Threading.Tasks;
 using HeuristicLab.Collections;
@@ -40,4 +41,6 @@
   [StorableClass]
   public sealed class TimeLimitRun : NamedItem, IOptimizer, IStorableContent, INotifyPropertyChanged {
+    private readonly ManualResetEvent signaler = new ManualResetEvent(true);
+
     public string Filename { get; set; }
 
@@ -238,5 +241,15 @@
     }
     public void Start() {
-      Algorithm.Start();
+      StartAsync().Wait();
+    }
+    public async Task StartAsync() {
+      await StartAsync(new CancellationToken());
+    }
+    public async Task StartAsync(CancellationToken cancellationToken) {
+      signaler.Reset();
+      await Task.Run(async () => {
+        await Algorithm.StartAsync(cancellationToken);
+        signaler.WaitOne();
+      }, cancellationToken);
     }
     public void Pause() {
@@ -282,4 +295,5 @@
     public event EventHandler Paused;
     private void OnPaused() {
+      if (!pausedForSnapshot && !pausedForTermination) signaler.Set();
       var handler = Paused;
       if (handler != null) handler(this, EventArgs.Empty);
@@ -287,4 +301,5 @@
     public event EventHandler Stopped;
     private void OnStopped() {
+      signaler.Set();
       var handler = Stopped;
       if (handler != null) handler(this, EventArgs.Empty);
@@ -336,11 +351,12 @@
     private void Algorithm_Paused(object sender, EventArgs e) {
       var action = pausedForTermination ? ExecutionState.Stopped : (pausedForSnapshot ? ExecutionState.Started : ExecutionState.Paused);
-      if (pausedForSnapshot || pausedForTermination) {
-        pausedForSnapshot = pausedForTermination = false;
+      bool pausedByLimit = pausedForSnapshot || pausedForTermination;
+      if (pausedByLimit) {
         MakeSnapshot();
         FindNextSnapshotTimeIndex(ExecutionTime);
       }
       OnPaused();
-      if (action == ExecutionState.Started) Algorithm.Start();
+      if (pausedByLimit) pausedForSnapshot = pausedForTermination = false;
+      if (action == ExecutionState.Started) Algorithm.StartAsync();
       else if (action == ExecutionState.Stopped) Algorithm.Stop();
     }
