/// <summary> /// Stages the files listed in the <see cref="FilesToStage"/> list. /// </summary> /// <param name="allFileStagingArtifacts">An optional collection to customize and receive information about the file staging process. /// For more information see <see cref="IFileStagingArtifact"/>.</param> /// <returns>A <see cref="System.Threading.Tasks.Task"/> that represents the asynchronous operation.</returns> /// <remarks>The staging operation runs asynchronously.</remarks> public async System.Threading.Tasks.Task StageFilesAsync(ConcurrentDictionary <Type, IFileStagingArtifact> allFileStagingArtifacts = null) { // stage all these files // TODO: align this copy with threadsafe implementation of the IList<> List <IFileStagingProvider> allFiles = this.FilesToStage == null ? new List <IFileStagingProvider>() : new List <IFileStagingProvider>(this.FilesToStage); //TODO: There is a threading issue doing this - expose a change tracking box directly and use a lock? if (this.FilesToStage != null && this.ResourceFiles == null) { this.ResourceFiles = new List <ResourceFile>(); //We're about to have some resource files } // now we have all files, send off to file staging machine System.Threading.Tasks.Task fileStagingTask = FileStagingLinkedSources.StageFilesAsync(allFiles, allFileStagingArtifacts); // wait for file staging async task await fileStagingTask.ConfigureAwait(continueOnCapturedContext : false); // now update Task with its new ResourceFiles foreach (IFileStagingProvider curFile in allFiles) { IEnumerable <ResourceFile> curStagedFiles = curFile.StagedFiles; foreach (ResourceFile curStagedFile in curStagedFiles) { this.ResourceFiles.Add(curStagedFile); } } }
/// <summary> /// Performs file staging and also issues the AddTaskCollection request for the set of tasks to add. /// </summary> /// <param name="tasksToAdd">The set of tasks to add.</param> /// <param name="namingFragment"></param> /// <returns></returns> private async Task StageFilesAndAddTasks( Dictionary <string, TrackedCloudTask> tasksToAdd, string namingFragment) { List <Models.TaskAddParameter> protoTasksToAdd = new List <Models.TaskAddParameter>(); this.CheckForCancellationOrTimeoutAndThrow(); // // Perform file staging // // list of all files to be staged across all Tasks List <IFileStagingProvider> allFiles = new List <IFileStagingProvider>(); // collect all files to be staged foreach (TrackedCloudTask trackedCloudTask in tasksToAdd.Values) { if (trackedCloudTask.Task.FilesToStage != null) { // add in the files for the current task allFiles.AddRange(trackedCloudTask.Task.FilesToStage); } } //This dictonary is only for the purpose of this batch add ConcurrentDictionary <Type, IFileStagingArtifact> legStagingArtifacts = new ConcurrentDictionary <Type, IFileStagingArtifact>(); //Add the file staging artifacts for this let to the overall bag so as to allow customers to track the file staging progress this._customerVisibleFileStagingArtifacts.Add(legStagingArtifacts); // now we have all files, send off to file staging machine System.Threading.Tasks.Task fileStagingTask = FileStagingLinkedSources.StageFilesAsync(allFiles, legStagingArtifacts, namingFragment); // wait for file staging async task await fileStagingTask.ConfigureAwait(continueOnCapturedContext : false); // now update each non-finalized Task with its new ResourceFiles foreach (TrackedCloudTask taskToAdd in tasksToAdd.Values) { //Update the resource files if the task hasn't already been finalized if (taskToAdd.Task.FilesToStage != null) { foreach (IFileStagingProvider curFile in taskToAdd.Task.FilesToStage) { IEnumerable <ResourceFile> curStagedFiles = curFile.StagedFiles; if (null != curStagedFiles && !((IReadOnly)taskToAdd.Task).IsReadOnly) { //TODO: There is a threading issue here -- lock this property down somehow? if (taskToAdd.Task.ResourceFiles == null) { taskToAdd.Task.ResourceFiles = new List <ResourceFile>(); } foreach (ResourceFile curStagedFile in curStagedFiles) { taskToAdd.Task.ResourceFiles.Add(curStagedFile); } } } //Mark the file staging collection as read only just incase there's another reference to it ConcurrentChangeTrackedList <IFileStagingProvider> filesToStageListImpl = taskToAdd.Task.FilesToStage as ConcurrentChangeTrackedList <IFileStagingProvider>; filesToStageListImpl.IsReadOnly = true; //Set read only } Models.TaskAddParameter protoTask = taskToAdd.GetProtocolTask(); protoTasksToAdd.Add(protoTask); } this.CheckForCancellationOrTimeoutAndThrow(); // // Fire the protocol add collection request // var asyncTask = this._jobOperations.ParentBatchClient.ProtocolLayer.AddTaskCollection( this._jobId, protoTasksToAdd, this._behaviorManager, this._parallelOptions.CancellationToken); var response = await asyncTask.ConfigureAwait(continueOnCapturedContext : false); // // Process the results of the add task collection request // this.ProcessProtocolAddTaskResults(response.Body.Value, tasksToAdd); }