private async System.Threading.Tasks.Task <List <JobModel> > ListJobsAsync(int min, int max) { List <JobModel> results = new List <JobModel>(); string uppperBound = string.Format("job-{0:D10}", max); string lowerBound = string.Format("job-{0:D10}", min); // TODO: Need to use the detail level to limit amount of data we download from the server // TODO: and increase the performace of listing jobs in the UI //var detailLevel = new ODATADetailLevel() { SelectClause = "name,state,creationTime" }; //if (string.IsNullOrEmpty(detailLevel.FilterClause)) //{ // detailLevel.FilterClause = string.Empty; //} //detailLevel.FilterClause += string.Format("(jobName le '{0}' and jobName gt '{1}')", uppperBound, lowerBound); //IEnumerableAsyncExtended<ICloudJob> jobList = this.WorkItem.ListJobs(detailLevel); // END TODO IEnumerableAsyncExtended <ICloudJob> jobList = this.WorkItem.ListJobs(); IAsyncEnumerator <ICloudJob> asyncEnumerator = jobList.GetAsyncEnumerator(); while (await asyncEnumerator.MoveNextAsync()) { results.Add(new JobModel(this, asyncEnumerator.Current)); } return(results); }
/// <summary> /// Lists the Tasks matching the specified filter options /// </summary> /// <param name="options">The options to use when querying for Tasks</param> /// <returns>The Tasks matching the specified filter options</returns> public IEnumerable <PSCloudTask> ListTasks(ListTaskOptions options) { if (options == null) { throw new ArgumentNullException("options"); } if ((string.IsNullOrEmpty(options.WorkItemName) || string.IsNullOrEmpty(options.JobName)) && options.Job == null) { throw new ArgumentNullException(Resources.GBT_NoJob); } // Get the single Task matching the specified name if (!string.IsNullOrEmpty(options.TaskName)) { WriteVerbose(string.Format(Resources.GBT_GetByName, options.TaskName, options.JobName, options.WorkItemName)); using (IWorkItemManager wiManager = options.Context.BatchOMClient.OpenWorkItemManager()) { ICloudTask task = wiManager.GetTask(options.WorkItemName, options.JobName, options.TaskName, additionalBehaviors: options.AdditionalBehaviors); PSCloudTask psTask = new PSCloudTask(task); return(new PSCloudTask[] { psTask }); } } // List Tasks using the specified filter else { if (options.MaxCount <= 0) { options.MaxCount = Int32.MaxValue; } string jName = options.Job == null ? options.JobName : options.Job.Name; ODATADetailLevel odata = null; if (!string.IsNullOrEmpty(options.Filter)) { WriteVerbose(string.Format(Resources.GBT_GetByOData, jName, options.MaxCount)); odata = new ODATADetailLevel(filterClause: options.Filter); } else { WriteVerbose(string.Format(Resources.GBT_GetNoFilter, jName, options.MaxCount)); } IEnumerableAsyncExtended <ICloudTask> tasks = null; if (options.Job != null) { tasks = options.Job.omObject.ListTasks(odata, options.AdditionalBehaviors); } else { using (IWorkItemManager wiManager = options.Context.BatchOMClient.OpenWorkItemManager()) { tasks = wiManager.ListTasks(options.WorkItemName, options.JobName, odata, options.AdditionalBehaviors); } } Func <ICloudTask, PSCloudTask> mappingFunction = t => { return(new PSCloudTask(t)); }; return(new PSAsyncEnumerable <PSCloudTask, ICloudTask>(tasks, mappingFunction).Take(options.MaxCount)); } }
/// <summary> /// Lists the Task files matching the specified filter options /// </summary> /// <param name="options">The options to use when querying for Task files</param> /// <returns>The Task files matching the specified filter options</returns> public IEnumerable <PSTaskFile> ListTaskFiles(ListTaskFileOptions options) { if (options == null) { throw new ArgumentNullException("options"); } if ((string.IsNullOrWhiteSpace(options.WorkItemName) || string.IsNullOrWhiteSpace(options.JobName) || string.IsNullOrWhiteSpace(options.TaskName)) && options.Task == null) { throw new ArgumentNullException(Resources.GBTF_NoTaskSpecified); } // Get the single Task file matching the specified name if (!string.IsNullOrEmpty(options.TaskFileName)) { WriteVerbose(string.Format(Resources.GBTF_GetByName, options.TaskFileName, options.TaskName)); using (IWorkItemManager wiManager = options.Context.BatchOMClient.OpenWorkItemManager()) { ITaskFile taskFile = wiManager.GetTaskFile(options.WorkItemName, options.JobName, options.TaskName, options.TaskFileName, options.AdditionalBehaviors); PSTaskFile psTaskFile = new PSTaskFile(taskFile); return(new PSTaskFile[] { psTaskFile }); } } // List Task files using the specified filter else { string tName = options.Task == null ? options.TaskName : options.Task.Name; ODATADetailLevel odata = null; if (!string.IsNullOrEmpty(options.Filter)) { WriteVerbose(string.Format(Resources.GBTF_GetByOData, tName)); odata = new ODATADetailLevel(filterClause: options.Filter); } else { WriteVerbose(string.Format(Resources.GBTF_NoFilter, tName)); } IEnumerableAsyncExtended <ITaskFile> taskFiles = null; if (options.Task != null) { taskFiles = options.Task.omObject.ListTaskFiles(options.Recursive, odata, options.AdditionalBehaviors); } else { using (IWorkItemManager wiManager = options.Context.BatchOMClient.OpenWorkItemManager()) { taskFiles = wiManager.ListTaskFiles(options.WorkItemName, options.JobName, options.TaskName, options.Recursive, odata, options.AdditionalBehaviors); } } Func <ITaskFile, PSTaskFile> mappingFunction = f => { return(new PSTaskFile(f)); }; return(PSAsyncEnumerable <PSTaskFile, ITaskFile> .CreateWithMaxCount( taskFiles, mappingFunction, options.MaxCount, () => WriteVerbose(string.Format(Resources.MaxCount, options.MaxCount)))); } }
/// <summary> /// Lists the vm files matching the specified filter options /// </summary> /// <param name="options">The options to use when querying for vm files</param> /// <returns>The vm files matching the specified filter options</returns> public IEnumerable <PSVMFile> ListVMFiles(ListVMFileOptions options) { if (options == null) { throw new ArgumentNullException("options"); } // Get the single vm file matching the specified name if (!string.IsNullOrEmpty(options.VMFileName)) { WriteVerbose(string.Format(Resources.GBVMF_GetByName, options.VMFileName, options.VMName)); using (IPoolManager poolManager = options.Context.BatchOMClient.OpenPoolManager()) { ITaskFile vmFile = poolManager.GetVMFile(options.PoolName, options.VMName, options.VMFileName, options.AdditionalBehaviors); PSVMFile psVMFile = new PSVMFile(vmFile); return(new PSVMFile[] { psVMFile }); } } // List vm files using the specified filter else { string vmName = options.VM == null ? options.VMName : options.VM.Name; ODATADetailLevel odata = null; string verboseLogString = null; if (!string.IsNullOrEmpty(options.Filter)) { verboseLogString = string.Format(Resources.GBVMF_GetByOData, vmName); odata = new ODATADetailLevel(filterClause: options.Filter); } else { verboseLogString = string.Format(Resources.GBVMF_NoFilter, vmName); } WriteVerbose(verboseLogString); IEnumerableAsyncExtended <ITaskFile> vmFiles = null; if (options.VM != null) { vmFiles = options.VM.omObject.ListVMFiles(options.Recursive, odata, options.AdditionalBehaviors); } else { using (IPoolManager poolManager = options.Context.BatchOMClient.OpenPoolManager()) { vmFiles = poolManager.ListVMFiles(options.PoolName, options.VMName, options.Recursive, odata, options.AdditionalBehaviors); } } Func <ITaskFile, PSVMFile> mappingFunction = f => { return(new PSVMFile(f)); }; return(PSAsyncEnumerable <PSVMFile, ITaskFile> .CreateWithMaxCount( vmFiles, mappingFunction, options.MaxCount, () => WriteVerbose(string.Format(Resources.MaxCount, options.MaxCount)))); } }
private async System.Threading.Tasks.Task <List <TvmModel> > ListVMsAsync() { List <TvmModel> results = new List <TvmModel>(); IEnumerableAsyncExtended <IVM> jobList = this.Pool.ListVMs(OptionsModel.Instance.ListDetailLevel); IAsyncEnumerator <IVM> asyncEnumerator = jobList.GetAsyncEnumerator(); while (await asyncEnumerator.MoveNextAsync()) { results.Add(new TvmModel(this, asyncEnumerator.Current)); } return(results); }
/// <summary> /// Lists the files on this TVM /// </summary> /// <returns></returns> private async System.Threading.Tasks.Task <List <ITaskFile> > ListFilesAsync() { List <ITaskFile> results = new List <ITaskFile>(); IEnumerableAsyncExtended <ITaskFile> vmFiles = this.VM.ListVMFiles(recursive: true); IAsyncEnumerator <ITaskFile> asyncEnumerator = vmFiles.GetAsyncEnumerator(); while (await asyncEnumerator.MoveNextAsync()) { results.Add(asyncEnumerator.Current); } return(results); }
internal PSAsyncEnumerable(IEnumerableAsyncExtended <T2> omAsyncEnumerable, Func <T2, T1> mappingFunction) { if (omAsyncEnumerable == null) { throw new ArgumentNullException("omAsyncEnumerable"); } this.omAsyncEnumerable = omAsyncEnumerable; if (mappingFunction == null) { throw new ArgumentNullException("mappingFunction"); } this.mappingFunction = mappingFunction; }
private async System.Threading.Tasks.Task <List <TaskModel> > ListTasksAsync() { List <TaskModel> results = new List <TaskModel>(); IEnumerableAsyncExtended <ICloudTask> taskList = this.Job.ListTasks(OptionsModel.Instance.ListDetailLevel); IAsyncEnumerator <ICloudTask> asyncEnumerator = taskList.GetAsyncEnumerator(); while (await asyncEnumerator.MoveNextAsync()) { results.Add(new TaskModel(this, asyncEnumerator.Current)); } return(results); }
/// <summary> /// Lists the Jobs matching the specified filter options /// </summary> /// <param name="options">The options to use when querying for Jobs</param> /// <returns>The Jobs matching the specified filter options</returns> public IEnumerable <PSCloudJob> ListJobs(ListJobOptions options) { if (options == null) { throw new ArgumentNullException("options"); } if (string.IsNullOrEmpty(options.WorkItemName) && options.WorkItem == null) { throw new ArgumentNullException(Resources.GBJ_NoWorkItem); } string wiName = options.WorkItem == null ? options.WorkItemName : options.WorkItem.Name; // Get the single Job matching the specified name if (!string.IsNullOrEmpty(options.JobName)) { WriteVerbose(string.Format(Resources.GBJ_GetByName, options.JobName, wiName)); using (IWorkItemManager wiManager = options.Context.BatchOMClient.OpenWorkItemManager()) { ICloudJob job = wiManager.GetJob(wiName, options.JobName, additionalBehaviors: options.AdditionalBehaviors); PSCloudJob psJob = new PSCloudJob(job); return(new PSCloudJob[] { psJob }); } } // List Jobs using the specified filter else { if (options.MaxCount <= 0) { options.MaxCount = Int32.MaxValue; } ODATADetailLevel odata = null; if (!string.IsNullOrEmpty(options.Filter)) { WriteVerbose(string.Format(Resources.GBJ_GetByOData, wiName, options.MaxCount)); odata = new ODATADetailLevel(filterClause: options.Filter); } else { WriteVerbose(string.Format(Resources.GBJ_GetNoFilter, wiName, options.MaxCount)); } using (IWorkItemManager wiManager = options.Context.BatchOMClient.OpenWorkItemManager()) { IEnumerableAsyncExtended <ICloudJob> jobs = wiManager.ListJobs(wiName, odata, options.AdditionalBehaviors); Func <ICloudJob, PSCloudJob> mappingFunction = j => { return(new PSCloudJob(j)); }; return(new PSAsyncEnumerable <PSCloudJob, ICloudJob>(jobs, mappingFunction).Take(options.MaxCount)); } } }
/// <summary> /// Refreshes the status of the VMs from the Batch service. /// </summary> /// <returns></returns> private async Task RefreshVMsAsync() { // Get the list of pool VM's - can't use this because IVM does not support RecentTasks property yet DetailLevel detailLevel = new ODATADetailLevel() { SelectClause = "recentTasks,state,name" }; IEnumerableAsyncExtended <IVM> vmEnumerableAsync = this.Pool.ListVMs(detailLevel); IAsyncEnumerator <IVM> enumerator = vmEnumerableAsync.GetAsyncEnumerator(); List <IVM> vmList = new List <IVM>(); while (await enumerator.MoveNextAsync()) { vmList.Add(enumerator.Current); } this.RunningTasks = 0; this.SchedulableVMs = 0; foreach (IVM poolVM in vmList) { if (poolVM.State == TVMState.Idle || poolVM.State == TVMState.Running) { this.SchedulableVMs++; } if (poolVM.State == TVMState.Running && this.Pool.MaxTasksPerVM == 1) { this.RunningTasks++; } else if (this.Pool.MaxTasksPerVM > 1) { IEnumerable <TaskInformation> taskInfoList = poolVM.RecentTasks; if (taskInfoList != null) { foreach (TaskInformation ti in taskInfoList) { if (ti.TaskState == TaskState.Running) { this.RunningTasks++; } } } } } Interlocked.Exchange(ref this.vms, vmList); //Threadsafe swap }
private async System.Threading.Tasks.Task <List <JobModel> > ListJobsAsync() { List <JobModel> results = new List <JobModel>(); var detailLevel = new ODATADetailLevel() { SelectClause = "name,state,creationTime" }; IEnumerableAsyncExtended <ICloudJob> jobList = this.WorkItem.ListJobs(detailLevel); IAsyncEnumerator <ICloudJob> asyncEnumerator = jobList.GetAsyncEnumerator(); while (await asyncEnumerator.MoveNextAsync()) { results.Add(new JobModel(this, asyncEnumerator.Current)); } return(results); }
/// <summary> /// Lists the vms matching the specified filter options /// </summary> /// <param name="options">The options to use when querying for vms</param> /// <returns>The vms matching the specified filter options</returns> public IEnumerable <PSVM> ListVMs(ListVMOptions options) { if (options == null) { throw new ArgumentNullException("options"); } string poolName = options.Pool == null ? options.PoolName : options.Pool.Name; // Get the single vm matching the specified name if (!string.IsNullOrEmpty(options.VMName)) { WriteVerbose(string.Format(Resources.GBVM_GetByName, options.VMName, poolName)); using (IPoolManager poolManager = options.Context.BatchOMClient.OpenPoolManager()) { IVM vm = poolManager.GetVM(poolName, options.VMName, additionalBehaviors: options.AdditionalBehaviors); PSVM psVM = new PSVM(vm); return(new PSVM[] { psVM }); } } // List vms using the specified filter else { ODATADetailLevel odata = null; string verboseLogString = null; if (!string.IsNullOrEmpty(options.Filter)) { verboseLogString = string.Format(Resources.GBVM_GetByOData, poolName); odata = new ODATADetailLevel(filterClause: options.Filter); } else { verboseLogString = string.Format(Resources.GBVM_NoFilter, poolName); } WriteVerbose(verboseLogString); using (IPoolManager poolManager = options.Context.BatchOMClient.OpenPoolManager()) { IEnumerableAsyncExtended <IVM> vms = poolManager.ListVMs(poolName, odata, options.AdditionalBehaviors); Func <IVM, PSVM> mappingFunction = v => { return(new PSVM(v)); }; return(PSAsyncEnumerable <PSVM, IVM> .CreateWithMaxCount( vms, mappingFunction, options.MaxCount, () => WriteVerbose(string.Format(Resources.MaxCount, options.MaxCount)))); } } }
internal static IEnumerable <T1> CreateWithMaxCount( IEnumerableAsyncExtended <T2> omAsyncEnumerable, Func <T2, T1> mappingFunction, int maxCount, Action logMaxCount = null) { PSAsyncEnumerable <T1, T2> asyncEnumerable = new PSAsyncEnumerable <T1, T2>(omAsyncEnumerable, mappingFunction); if (maxCount <= 0) { return(asyncEnumerable); } else { if (logMaxCount != null) { logMaxCount(); } return(asyncEnumerable.Take(maxCount)); } }
/// <summary> /// Lists the workitems matching the specified filter options /// </summary> /// <param name="options">The options to use when querying for workitems</param> /// <returns>The workitems matching the specified filter options</returns> public IEnumerable <PSCloudWorkItem> ListWorkItems(ListWorkItemOptions options) { if (options == null) { throw new ArgumentNullException("options"); } // Get the single WorkItem matching the specified name if (!string.IsNullOrWhiteSpace(options.WorkItemName)) { WriteVerbose(string.Format(Resources.GBWI_GetByName, options.WorkItemName)); using (IWorkItemManager wiManager = options.Context.BatchOMClient.OpenWorkItemManager()) { ICloudWorkItem workItem = wiManager.GetWorkItem(options.WorkItemName, additionalBehaviors: options.AdditionalBehaviors); PSCloudWorkItem psWorkItem = new PSCloudWorkItem(workItem); return(new PSCloudWorkItem[] { psWorkItem }); } } // List WorkItems using the specified filter else { ODATADetailLevel odata = null; string verboseLogString = null; if (!string.IsNullOrEmpty(options.Filter)) { verboseLogString = Resources.GBWI_GetByOData; odata = new ODATADetailLevel(filterClause: options.Filter); } else { verboseLogString = Resources.GBWI_NoFilter; } WriteVerbose(verboseLogString); using (IWorkItemManager wiManager = options.Context.BatchOMClient.OpenWorkItemManager()) { IEnumerableAsyncExtended <ICloudWorkItem> workItems = wiManager.ListWorkItems(odata, options.AdditionalBehaviors); Func <ICloudWorkItem, PSCloudWorkItem> mappingFunction = w => { return(new PSCloudWorkItem(w)); }; return(PSAsyncEnumerable <PSCloudWorkItem, ICloudWorkItem> .CreateWithMaxCount( workItems, mappingFunction, options.MaxCount, () => WriteVerbose(string.Format(Resources.MaxCount, options.MaxCount)))); } } }
/// <summary> /// Lists the pools matching the specified filter options /// </summary> /// <param name="options">The options to use when querying for pools</param> /// <returns>The pools matching the specified filter options</returns> public IEnumerable <PSCloudPool> ListPools(ListPoolOptions options) { if (options == null) { throw new ArgumentNullException("options"); } // Get the single pool matching the specified name if (!string.IsNullOrWhiteSpace(options.PoolName)) { WriteVerbose(string.Format(Resources.GBP_GetByName, options.PoolName)); using (IPoolManager poolManager = options.Context.BatchOMClient.OpenPoolManager()) { ICloudPool pool = poolManager.GetPool(options.PoolName, additionalBehaviors: options.AdditionalBehaviors); PSCloudPool psPool = new PSCloudPool(pool); return(new PSCloudPool[] { psPool }); } } // List pools using the specified filter else { ODATADetailLevel odata = null; string verboseLogString = null; if (!string.IsNullOrEmpty(options.Filter)) { verboseLogString = Resources.GBP_GetByOData; odata = new ODATADetailLevel(filterClause: options.Filter); } else { verboseLogString = Resources.GBP_NoFilter; } WriteVerbose(verboseLogString); using (IPoolManager poolManager = options.Context.BatchOMClient.OpenPoolManager()) { IEnumerableAsyncExtended <ICloudPool> pools = poolManager.ListPools(odata, options.AdditionalBehaviors); Func <ICloudPool, PSCloudPool> mappingFunction = p => { return(new PSCloudPool(p)); }; return(PSAsyncEnumerable <PSCloudPool, ICloudPool> .CreateWithMaxCount( pools, mappingFunction, options.MaxCount, () => WriteVerbose(string.Format(Resources.MaxCount, options.MaxCount)))); } } }
/// <summary> /// Runs the job manager task. /// </summary> public async Task RunAsync() { Console.WriteLine("JobManager for account: {0}, work item: {1}, job: {2} has started...", this.accountName, this.workItemName, this.jobName); Console.WriteLine(); Console.WriteLine("JobManager running with the following settings: "); Console.WriteLine("----------------------------------------"); Console.WriteLine(this.configurationSettings.ToString()); //Set up the Batch Service credentials used to authenticate with the Batch Service. BatchCredentials batchCredentials = new BatchCredentials( this.configurationSettings.BatchAccountName, this.configurationSettings.BatchAccountKey); using (IBatchClient batchClient = BatchClient.Connect(this.configurationSettings.BatchServiceUrl, batchCredentials)) { using (IWorkItemManager workItemManager = batchClient.OpenWorkItemManager()) { IToolbox toolbox = batchClient.OpenToolbox(); //Construct a container SAS to provide the Batch Service access to the files required to //run the mapper and reducer tasks. string containerSas = Helpers.ConstructContainerSas( this.configurationSettings.StorageAccountName, this.configurationSettings.StorageAccountKey, this.configurationSettings.StorageServiceUrl, this.configurationSettings.BlobContainer); // // Submit mapper tasks. // Console.WriteLine("Submitting {0} mapper tasks.", this.configurationSettings.NumberOfMapperTasks); //The collection of tasks to add to the Batch Service. List <ICloudTask> tasksToAdd = new List <ICloudTask>(); for (int i = 0; i < this.configurationSettings.NumberOfMapperTasks; i++) { string taskName = Helpers.GetMapperTaskName(i); string fileBlobName = Helpers.GetSplitFileName(i); string fileBlobPath = Helpers.ConstructBlobSource(containerSas, fileBlobName); string commandLine = string.Format("{0} -MapperTask {1}", Constants.TextSearchExe, fileBlobPath); ICloudTask unboundMapperTask = new CloudTask(taskName, commandLine); //The set of files (exe's, dll's and configuration files) required to run the mapper task. IReadOnlyList <string> mapperTaskRequiredFiles = Constants.RequiredExecutableFiles; List <IResourceFile> mapperTaskResourceFiles = Helpers.GetResourceFiles(containerSas, mapperTaskRequiredFiles); unboundMapperTask.ResourceFiles = mapperTaskResourceFiles; tasksToAdd.Add(unboundMapperTask); } //Submit the unbound task collection to the Batch Service. //Use the AddTask method which takes a collection of ICloudTasks for the best performance. await workItemManager.AddTaskAsync(this.workItemName, this.jobName, tasksToAdd); // // Wait for the mapper tasks to complete. // Console.WriteLine("Waiting for the mapper tasks to complete..."); //List all the mapper tasks using a name filter. DetailLevel mapperTaskNameFilter = new ODATADetailLevel() { FilterClause = string.Format("startswith(name, '{0}')", Constants.MapperTaskPrefix) }; List <ICloudTask> tasksToMonitor = workItemManager.ListTasks( this.workItemName, this.jobName, detailLevel: mapperTaskNameFilter).ToList(); //Use the task state monitor to wait for the tasks to complete. ITaskStateMonitor taskStateMonitor = toolbox.CreateTaskStateMonitor(); bool timedOut = await taskStateMonitor.WaitAllAsync(tasksToMonitor, TaskState.Completed, TimeSpan.FromMinutes(5)); //Get the list of mapper tasks in order to analyze their state and ensure they completed successfully. IEnumerableAsyncExtended <ICloudTask> asyncEnumerable = workItemManager.ListTasks( this.workItemName, this.jobName, detailLevel: mapperTaskNameFilter); IAsyncEnumerator <ICloudTask> asyncEnumerator = asyncEnumerable.GetAsyncEnumerator(); //Dump the status of each mapper task. while (await asyncEnumerator.MoveNextAsync()) { ICloudTask cloudTask = asyncEnumerator.Current; Console.WriteLine("Task {0} is in state: {1}", cloudTask.Name, cloudTask.State); await Helpers.CheckForTaskSuccessAsync(cloudTask, dumpStandardOutOnTaskSuccess : false); Console.WriteLine(); } //If not all the tasks reached the desired state within the timeout then the job manager //cannot continue. if (timedOut) { const string errorMessage = "Mapper tasks did not complete within expected timeout."; Console.WriteLine(errorMessage); throw new TimeoutException(errorMessage); } // // Create the reducer task. // string reducerTaskCommandLine = string.Format("{0} -ReducerTask", Constants.TextSearchExe); Console.WriteLine("Adding the reducer task: {0}", Constants.ReducerTaskName); ICloudTask unboundReducerTask = new CloudTask(Constants.ReducerTaskName, reducerTaskCommandLine); //The set of files (exe's, dll's and configuration files) required to run the reducer task. List <IResourceFile> reducerTaskResourceFiles = Helpers.GetResourceFiles(containerSas, Constants.RequiredExecutableFiles); unboundReducerTask.ResourceFiles = reducerTaskResourceFiles; //Send the request to the Batch Service to add the reducer task. await workItemManager.AddTaskAsync(this.workItemName, this.jobName, unboundReducerTask); // //Wait for the reducer task to complete. // //Get the bound reducer task and monitor it for completion. ICloudTask boundReducerTask = await workItemManager.GetTaskAsync(this.workItemName, this.jobName, Constants.ReducerTaskName); timedOut = await taskStateMonitor.WaitAllAsync(new List <ICloudTask> { boundReducerTask }, TaskState.Completed, TimeSpan.FromMinutes(2)); //Refresh the reducer task to get the most recent information about it from the Batch Service. await boundReducerTask.RefreshAsync(); //Dump the reducer tasks exit code and scheduling error for debugging purposes. await Helpers.CheckForTaskSuccessAsync(boundReducerTask, dumpStandardOutOnTaskSuccess : true); //Handle the possibilty that the reducer task did not complete in the expected timeout. if (timedOut) { const string errorMessage = "Reducer task did not complete within expected timeout."; Console.WriteLine("Task {0} is in state: {1}", boundReducerTask.Name, boundReducerTask.State); Console.WriteLine(errorMessage); throw new TimeoutException(errorMessage); } //The job manager has completed. Console.WriteLine("JobManager completed successfully."); } } }