Index: branches/ParallelExperiment/HeuristicLab.Optimization.Views/3.3/IOptimizerView.cs
===================================================================
--- branches/ParallelExperiment/HeuristicLab.Optimization.Views/3.3/IOptimizerView.cs	(revision 15369)
+++ branches/ParallelExperiment/HeuristicLab.Optimization.Views/3.3/IOptimizerView.cs	(revision 15373)
@@ -136,6 +136,6 @@
 
     #region Control events
-    protected virtual void startButton_Click(object sender, EventArgs e) {
-      Content.StartAsync();
+    protected virtual async void startButton_Click(object sender, EventArgs e) {
+      await Content.StartAsync();
     }
     protected virtual void pauseButton_Click(object sender, EventArgs e) {
Index: branches/ParallelExperiment/HeuristicLab.Optimization/3.3/Algorithms/BasicAlgorithm.cs
===================================================================
--- branches/ParallelExperiment/HeuristicLab.Optimization/3.3/Algorithms/BasicAlgorithm.cs	(revision 15369)
+++ branches/ParallelExperiment/HeuristicLab.Optimization/3.3/Algorithms/BasicAlgorithm.cs	(revision 15373)
@@ -82,5 +82,5 @@
       } catch (OperationCanceledException) {
       } catch (AggregateException ae) {
-        OnExceptionOccurred(ae.InnerExceptions.SingleOrDefault() ?? ae);
+        ae.FlattenAndHandle(new[] { typeof(OperationCanceledException) }, e => OnExceptionOccurred(e));
       } catch (Exception e) {
         OnExceptionOccurred(e);
Index: branches/ParallelExperiment/HeuristicLab.Optimization/3.3/MetaOptimizers/Experiment.cs
===================================================================
--- branches/ParallelExperiment/HeuristicLab.Optimization/3.3/MetaOptimizers/Experiment.cs	(revision 15369)
+++ branches/ParallelExperiment/HeuristicLab.Optimization/3.3/MetaOptimizers/Experiment.cs	(revision 15373)
@@ -122,6 +122,5 @@
     private bool experimentStopped = false;
 
-    private ManualResetEventSlim allOptimizerFinished; // this indicates that all started optimizers have been paused or stopped
-    private SemaphoreSlim availableWorkers; // limits the number of concurrent optimizer executions
+    private readonly ManualResetEventSlim allOptimizerFinished = new ManualResetEventSlim(false); // this indicates that all started optimizers have been paused or stopped
 
     public Experiment()
@@ -202,31 +201,37 @@
       Start(CancellationToken.None);
     }
-
     public void Start(CancellationToken cancellationToken) {
       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;
+      if (!Optimizers.Any(x => x.ExecutionState == ExecutionState.Prepared || x.ExecutionState == ExecutionState.Paused)) return;
 
       experimentStarted = true;
       experimentStopped = false;
-      allOptimizerFinished = new ManualResetEventSlim(false);
-      availableWorkers = new SemaphoreSlim(NumberOfWorkers, NumberOfWorkers);
-
-      var runnableOptimizers = Optimizers.Where(o => o.ExecutionState == ExecutionState.Prepared || o.ExecutionState == ExecutionState.Paused).ToList();
-      if (!runnableOptimizers.Any()) return;
-
-      while (runnableOptimizers.Any()) {
-        try {
-          availableWorkers.Wait(cancellationToken); // an optimizer was pause/stopped previously
-          if (experimentStopped || !experimentStarted) break;
-          // some optimizers might be started manually somewhere else
-          runnableOptimizers.RemoveAll(o => !(o.ExecutionState == ExecutionState.Prepared || o.ExecutionState == ExecutionState.Paused));
-          var optimizer = runnableOptimizers.FirstOrDefault();
-          runnableOptimizers.Remove(optimizer);
-          optimizer?.StartAsync(cancellationToken);
-        } catch (InvalidOperationException) { } catch (OperationCanceledException) { }
-      }
-
-      allOptimizerFinished.Wait();
+
+      var startedTasks = new List<Task>();
+      using (var availableWorkers = new SemaphoreSlim(NumberOfWorkers, NumberOfWorkers)) {
+        var runnableOptimizers = Optimizers.Where(o => o.ExecutionState == ExecutionState.Prepared || o.ExecutionState == ExecutionState.Paused).ToList();
+        if (!runnableOptimizers.Any()) return;
+
+        while (runnableOptimizers.Any()) {
+          try {
+            availableWorkers.Wait(cancellationToken);
+            if (experimentStopped || !experimentStarted) break;
+            // some optimizers might be started manually somewhere else
+            runnableOptimizers.RemoveAll(o => !(o.ExecutionState == ExecutionState.Prepared || o.ExecutionState == ExecutionState.Paused));
+            if (runnableOptimizers.Any()) {
+              var optimizer = runnableOptimizers.First();
+              runnableOptimizers.Remove(optimizer);
+              var startedTask = optimizer.StartAsync(cancellationToken).ContinueWith(x => {
+                availableWorkers.Release(); // is not disposed yet because Task.WaitAll at the end of the using is blocking
+              });
+              startedTasks.Add(startedTask);
+            }
+          } catch (InvalidOperationException) { } catch (OperationCanceledException) { }
+        }
+
+        allOptimizerFinished.Wait();
+        Task.WaitAll(startedTasks.ToArray()); // retreive exeptions of the asyncrounously started optimizer
+      }
     }
     public async Task StartAsync() { await StartAsync(CancellationToken.None); }
@@ -294,14 +299,14 @@
     private void OnPaused() {
       ExecutionState = ExecutionState.Paused;
+      allOptimizerFinished.Set();
       EventHandler handler = Paused;
       if (handler != null) handler(this, EventArgs.Empty);
-      allOptimizerFinished.Set();
     }
     public event EventHandler Stopped;
     private void OnStopped() {
       ExecutionState = ExecutionState.Stopped;
+      allOptimizerFinished.Set();
       EventHandler handler = Stopped;
       if (handler != null) handler(this, EventArgs.Empty);
-      allOptimizerFinished.Set();
     }
     public event EventHandler<EventArgs<Exception>> ExceptionOccurred;
@@ -398,6 +403,4 @@
     private void optimizer_Paused(object sender, EventArgs e) {
       lock (locker) {
-        if (availableWorkers.CurrentCount < NumberOfWorkers)
-          availableWorkers.Release();
         if (Optimizers.All(x => x.ExecutionState != ExecutionState.Started)) {
           OnPaused();
@@ -415,10 +418,6 @@
     private void optimizer_Stopped(object sender, EventArgs e) {
       lock (locker) {
-        if (availableWorkers.CurrentCount < NumberOfWorkers)
-          availableWorkers.Release();
         if (experimentStopped) {
-          if (Optimizers.All(x => (x.ExecutionState == ExecutionState.Stopped) || (x.ExecutionState == ExecutionState.Prepared))) {
-            OnStopped();
-          }
+          if (Optimizers.All(x => (x.ExecutionState == ExecutionState.Stopped) || (x.ExecutionState == ExecutionState.Prepared))) OnStopped();
         } else {
           if (experimentStarted && Optimizers.Any(x => (x.ExecutionState == ExecutionState.Prepared) || (x.ExecutionState == ExecutionState.Paused))) return;
