public async Task RunAndCheckSolution(Guid solutionId, ExerciseData[] testData) { if (blackList.Contains(solutionId)) { // TODO what? logger.LogError($"solution from black list {solutionId}"); return; } CancellationTokenSource source = new CancellationTokenSource(); Task[] workTasks = null; try { currentStart = DateTime.Now; CurrentTestDataCount = testData.Length; Current = solutionId; var imageName = $"solution:{solutionId}"; ConcurrentQueue <SolutionStatus> statuses = new ConcurrentQueue <SolutionStatus>(); workTasks = Enumerable .Range(1, runningSettings.WorkersPerCheckCount) .Select(_ => HandleSolutionWorker( solutionId, imageName, testData, (s) => statuses.Enqueue(s), source.Token)) .ToArray(); await Task.WhenAll(workTasks); var result = statuses.DefaultIfEmpty(SolutionStatus.Successful).Min(); logger.LogInformation($"{solutionId} TOTAL STATUS {result}"); await solutionsBase.SaveChanges(solutionId, result); await dockerClient.Images.DeleteImageAsync(imageName, new ImageDeleteParameters { Force = true, NoPrune = false }); } catch (Exception ex) { blackList.Add(solutionId); logger.LogError(ex, "Critical error"); source.Cancel(); if (workTasks != null) { foreach (var task in workTasks.Where(t => t != null)) { task.ContinueWith(t => { if (t.IsFaulted) { logger.LogError(t.Exception, "Critical error on worker"); } }).Wait(); } } } finally { Current = null; currentTestDataIndex = -1; currentTestDataChecked = 0; CurrentTestDataCount = 0; } }