Changeset 15375
- Timestamp:
- 09/20/17 15:12:10 (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/ParallelExperiment/HeuristicLab.Optimization/3.3/MetaOptimizers/Experiment.cs
r15373 r15375 204 204 if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused)) 205 205 throw new InvalidOperationException(string.Format("Start not allowed in execution state \"{0}\".", ExecutionState)); 206 if (!Optimizers.Any(x => x.ExecutionState == ExecutionState.Prepared || x.ExecutionState == ExecutionState.Paused)) return; 206 207 // Multiple enumerations of runnableOptimizers is done on purpose to get the latest list of runnnable optimizers lazily 208 var runnableOptimizers = Optimizers.Where(x => x.ExecutionState == ExecutionState.Prepared || x.ExecutionState == ExecutionState.Paused); 209 if (!runnableOptimizers.Any()) return; 207 210 208 211 experimentStarted = true; 209 212 experimentStopped = false; 210 213 211 var started Tasks = new List<Task>();214 var startedOptimizers = new Dictionary<IOptimizer, Task>(); // track already started optimizers (.StartAsync does not set the executionstate immediately) 212 215 using (var availableWorkers = new SemaphoreSlim(NumberOfWorkers, NumberOfWorkers)) { 213 var runnableOptimizers = Optimizers.Where(o => o.ExecutionState == ExecutionState.Prepared || o.ExecutionState == ExecutionState.Paused).ToList(); 214 if (!runnableOptimizers.Any()) return; 215 216 while (runnableOptimizers.Any()) { 216 while (runnableOptimizers.Any(o => !startedOptimizers.ContainsKey(o))) { 217 217 try { 218 218 availableWorkers.Wait(cancellationToken); 219 219 if (experimentStopped || !experimentStarted) break; 220 // some optimizers might be started manually somewhere else 221 runnableOptimizers.RemoveAll(o => !(o.ExecutionState == ExecutionState.Prepared || o.ExecutionState == ExecutionState.Paused)); 222 if (runnableOptimizers.Any()) { 223 var optimizer = runnableOptimizers.First(); 224 runnableOptimizers.Remove(optimizer); 225 var startedTask = optimizer.StartAsync(cancellationToken).ContinueWith(x => { 226 availableWorkers.Release(); // is not disposed yet because Task.WaitAll at the end of the using is blocking 220 var optimizer = runnableOptimizers.FirstOrDefault(o => !startedOptimizers.ContainsKey(o)); 221 if (optimizer != null) { 222 var startedTask = optimizer.StartAsync(cancellationToken).ContinueWith(async t => { 223 availableWorkers.Release(); // is guaranteed to be not disposed yet because Task.WaitAll blocks before the end of the using 224 await t; // trigger a potential exception on the optimizerTask 227 225 }); 228 started Tasks.Add(startedTask);226 startedOptimizers.Add(optimizer, startedTask.Unwrap()); // unwrap task because lambda of .ContinueWith is async 229 227 } 230 228 } catch (InvalidOperationException) { } catch (OperationCanceledException) { } 231 229 } 232 230 231 Task.WaitAll(startedOptimizers.Values.ToArray()); // retreive exeptions of the asyncrounously started optimizer 233 232 allOptimizerFinished.Wait(); 234 Task.WaitAll(startedTasks.ToArray()); // retreive exeptions of the asyncrounously started optimizer235 233 } 236 234 }
Note: See TracChangeset
for help on using the changeset viewer.