public async Task RunTasks(StudyInfo study, HallOfFame hof, HallOfFame complete) { if (hof == null && complete == null) { return; } var toRun = (_useComplete && complete != null) ? complete : hof; _folder = study.Folder + "\\screenshots"; if (!System.IO.Directory.Exists(_folder)) { System.IO.Directory.CreateDirectory(_folder); } // Shouldn't really be necessary _maxItems = toRun.solutions.Length; if ( Start >= 0 && Start < _maxItems && Items >= 0 && Items <= _maxItems && Start + Items <= _maxItems ) { bool waiting = false; int counter = Start; var images = new Bitmap[_maxItems]; var errorImages = new Bitmap[_maxItems]; var runsWithErrors = new List <int>(); Progress = 0; Escape = false; // Pre-load any existing images that come before the chosen range, if this option was selected if (_createAnimations && _loadImages && counter > 0) { LoadExistingImages(images, _captureErrors ? errorImages : null, _folder, 0, counter); } _previousRunType = _dynamoViewModel.HomeSpace.RunSettings.RunType; _dynamoViewModel.HomeSpace.RunSettings.RunType = Dynamo.Models.RunType.Manual; // Define and attach the main post-execution handler ExecutionStateHandler postExecution = async(e) => { DoEvents(); await Task.Delay(3000); waiting = false; if (!_escapePressed) { var isError = false; if (_captureErrors) { // Does the graph contain any nodes in an error state? var errorNodes = (from n in _readyParams.CurrentWorkspaceModel.Nodes where n.State != ElementState.Active && n.State != ElementState.Dead select n); if (errorNodes.Count <NodeModel>() > 0) { isError = true; runsWithErrors.Add(counter); } } var img = SaveScreenshot(GetImageFilename(_folder, counter, isError)); if (isError) { errorImages[counter] = img; } else { images[counter] = img; } counter++; var captured = counter - Start; Progress = 100 * captured / Items; } }; ExecutionEvents.GraphPostExecution += postExecution; if (Items == 0) { Progress = 100; } else { var nodeMap = GetDynamoNodesForInputParameters(toRun.variables, _readyParams.CurrentWorkspaceModel.Nodes); for (int i = Start; i < Start + Items; i++) { if (_escapePressed) { break; } var parameters = toRun.solutions[i]; for (var j = 0; j < toRun.variables.Length; j++) { SetDynamoInputParameter(nodeMap, toRun.variables[j], parameters[toRun.goals.Length + j]); } waiting = true; StartDynamoRun(); while (waiting) { await Task.Delay(1000); } } } _dynamoViewModel.HomeSpace.RunSettings.RunType = _previousRunType; // Post-load any existing images that come after the chosen range, if this option was selected if (_createAnimations && _loadImages && counter + 1 < _maxItems) { LoadExistingImages(images, _captureErrors ? errorImages : null, _folder, counter + 1, _maxItems); } if (!_escapePressed) { if (_createAnimations) { var levels = GetSortLevels(); var order = GetSolutionOrder(toRun, levels); var rootName = StripInvalidFileAndPathCharacters(_rootName); if (!images.All <Bitmap>((b) => b == null)) { SaveAnimation(images, order, _folder + "\\" + rootName + ".gif"); SaveAnimation(images, order, _folder + "\\" + rootName + "-small.gif", 1000); SaveAnimation(images, order, _folder + "\\" + rootName + "-tiny.gif", 500); } if (!errorImages.All <Bitmap>((b) => b == null)) { SaveAnimation(errorImages, order, _folder + "\\" + rootName + "-errors.gif"); SaveAnimation(errorImages, order, _folder + "\\" + rootName + "-errors-small.gif", 1000); SaveAnimation(errorImages, order, _folder + "\\" + rootName + "-errors-tiny.gif", 500); } } // If errors were found in any of the runs, create a new run with just the problematic runs const string errorsSuffix = "-errors"; if (_captureErrors && runsWithErrors.Count > 0 && !study.Folder.EndsWith(errorsSuffix)) { SaveFilteredHallOfFame(study, study.Folder + errorsSuffix, runsWithErrors); OnPropertyChanged("RefineryTasks"); } } foreach (var image in images) { if (image != null) { image.Dispose(); } } foreach (var image in errorImages) { if (image != null) { image.Dispose(); } } DisableExecute(false); ExecutionEvents.GraphPostExecution -= postExecution; var result = MessageBox.Show("Capture complete. Copy output path to the clipboard?", "Confirmation", MessageBoxButton.YesNo, MessageBoxImage.Question); if (result == MessageBoxResult.Yes) { Clipboard.SetText(_folder); } } }