< Summary

Class:Microsoft.Azure.Batch.JobOperations
Assembly:Microsoft.Azure.Batch
File(s):C:\Git\azure-sdk-for-net\sdk\batch\Microsoft.Azure.Batch\src\JobOperations.cs
Covered lines:222
Uncovered lines:69
Coverable lines:291
Total lines:1274
Line coverage:76.2% (222 of 291)
Covered branches:3
Total branches:4
Branch coverage:75% (3 of 4)

Metrics

MethodCyclomatic complexity Line coverage Branch coverage
.ctor()-0%100%
.ctor(...)-100%100%
get_CustomBehaviors()-100%100%
CreateJob()-100%100%
CreateJob(...)-100%100%
ListJobsImpl(...)-100%100%
ListJobs(...)-100%100%
GetJobAsyncImpl()-100%100%
GetJobAsync()-100%100%
GetJob(...)-100%100%
GetJobTaskCountsAsyncImpl()-50%100%
GetJobTaskCountsAsync()-50%100%
GetJobTaskCounts(...)-0%100%
EnableJobAsync()-75%100%
EnableJob(...)-0%100%
DisableJobAsync()-75%100%
DisableJob(...)-0%100%
TerminateJobAsync()-75%100%
TerminateJob(...)-0%100%
DeleteJobAsync()-75%100%
DeleteJob(...)-0%100%
ListTasksImpl(...)-100%100%
ListTasks(...)-100%100%
GetTaskAsyncImpl()-100%100%
GetTaskAsync(...)-100%100%
GetTask(...)-100%100%
ListSubtasks(...)-100%100%
AddTaskAsyncImpl()-91.67%75%
AddTaskAsync(...)-100%100%
AddTask(...)-0%100%
ListNodeFilesImpl(...)-100%100%
ListSubtasksImpl(...)-100%100%
ListNodeFiles(...)-100%100%
TerminateTaskAsync(...)-100%100%
TerminateTask(...)-0%100%
DeleteTaskAsync(...)-100%100%
DeleteTask(...)-0%100%
ReactivateTaskAsync(...)-100%100%
ReactivateTask(...)-0%100%
GetNodeFileAsyncImpl()-100%100%
GetNodeFileAsync(...)-100%100%
GetNodeFile(...)-0%100%
CopyNodeFileContentToStreamAsyncImpl()-88.89%100%
CopyNodeFileContentToStreamAsync(...)-100%100%
CopyNodeFileContentToStream(...)-0%100%
CopyNodeFileContentToStringAsyncImpl(...)-100%100%
CopyNodeFileContentToStringAsync(...)-100%100%
CopyNodeFileContentToString(...)-0%100%
DeleteNodeFileAsync()-90%100%
DeleteNodeFile(...)-0%100%
AddTaskAsyncImpl(...)-100%100%
AddTaskAsync()-88.89%100%
AddTask(...)-0%100%
GetAllLifetimeStatisticsAsync()-66.67%100%
GetAllLifetimeStatistics(...)-0%100%
ListJobPreparationAndReleaseTaskStatus(...)-100%100%
get_ParentBatchClient()-100%100%

File(s)

C:\Git\azure-sdk-for-net\sdk\batch\Microsoft.Azure.Batch\src\JobOperations.cs

#LineLine coverage
 1// Copyright (c) Microsoft Corporation. All rights reserved.
 2// Licensed under the MIT License. See License.txt in the project root for license information.
 3
 4using System.IO;
 5
 6namespace Microsoft.Azure.Batch
 7{
 8    using System;
 9    using System.Collections.Generic;
 10    using System.Collections.Concurrent;
 11    using System.Linq;
 12    using System.Text;
 13    using System.Security;
 14    using System.Threading;
 15    using System.Threading.Tasks;
 16
 17    using Microsoft.Azure.Batch.Common;
 18    using Models = Microsoft.Azure.Batch.Protocol.Models;
 19    using Microsoft.Rest.Azure;
 20
 21    /// <summary>
 22    /// Performs operations on Azure Batch jobs.
 23    /// </summary>
 24    /// <seealso cref="CloudJob"/>
 25    public class JobOperations : IInheritedBehaviors
 26    {
 27
 28#region // constructors
 29
 030        private JobOperations()
 31        {
 032        }
 33
 5634        internal JobOperations(BatchClient parentBatchClient, IEnumerable<BatchClientBehavior> inheritedBehaviors)
 35        {
 5636            this.ParentBatchClient = parentBatchClient;
 37
 38            // set up the behavior inheritance
 5639            InheritUtil.InheritClientBehaviorsAndSetPublicProperty(this, inheritedBehaviors);
 5640        }
 41
 42        #endregion //constructors
 43
 44
 45        #region IInheritedBehaviors
 46
 47        /// <summary>
 48        /// Gets or sets a list of behaviors that modify or customize requests to the Batch service
 49        /// made via this <see cref="JobOperations"/>.
 50        /// </summary>
 51        /// <remarks>
 52        /// <para>These behaviors are inherited by child objects.</para>
 53        /// <para>Modifications are applied in the order of the collection. The last write wins.</para>
 54        /// </remarks>
 25155        public IList<BatchClientBehavior> CustomBehaviors { get; set; }
 56
 57#endregion IInheritedBehaviors
 58
 59#region // JobOperations
 60
 61        /// <summary>
 62        /// Creates an instance of CloudJob that is unbound and does not have a consistency relationship to any job in t
 63        /// </summary>
 64        /// <returns>A <see cref="CloudJob"/> representing a new job that has not been submitted to the Batch service.</
 65        public CloudJob CreateJob()
 66        {
 367            CloudJob unboundJob = new CloudJob(this.ParentBatchClient, this.CustomBehaviors);
 68
 69            //TODO: Do we want to do this...?
 370            unboundJob.Id = Guid.NewGuid().ToString(); // we lose the ability to construct an unbound job with zero chan
 71
 372            return unboundJob;
 73        }
 74
 75        /// <summary>
 76        /// Creates an instance of CloudJob that is unbound and does not have a consistency relationship to any job in t
 77        /// </summary>
 78        /// <param name="jobId">The Id of the job.</param>
 79        /// <param name="poolInformation">The information about the pool the job will run on.</param>
 80        /// <returns>A <see cref="CloudJob"/> representing a new job that has not been submitted to the Batch service.</
 81        public CloudJob CreateJob(string jobId, PoolInformation poolInformation)
 82        {
 483            CloudJob unboundJob = new CloudJob(this.ParentBatchClient, this.CustomBehaviors)
 484                                  {
 485                                      Id = jobId,
 486                                      PoolInformation = poolInformation
 487                                  };
 88
 489            return unboundJob;
 90        }
 91
 92        internal IPagedEnumerable<CloudJob> ListJobsImpl(BehaviorManager bhMgr, DetailLevel detailLevel)
 93        {
 294            PagedEnumerable<CloudJob> enumerable = new PagedEnumerable<CloudJob>( // the lamda will be the enumerator fa
 295                () =>
 296                {
 297                    // here is the actual strongly typed enumerator
 498                    AsyncListJobsEnumerator typedEnumerator = new AsyncListJobsEnumerator(this.ParentBatchClient, bhMgr,
 299
 2100                    // here is the base
 2101                    PagedEnumeratorBase<CloudJob> enumeratorBase = typedEnumerator;
 2102
 4103                    return enumeratorBase;
 2104                });
 105
 2106            return enumerable;
 107        }
 108
 109        /// <summary>
 110        /// Enumerates the <see cref="CloudJob">jobs</see> in the Batch account.
 111        /// </summary>
 112        /// <param name="detailLevel">A <see cref="DetailLevel"/> used for filtering the list and for controlling which 
 113        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 114        /// <returns>An <see cref="IPagedEnumerable{CloudJob}"/> that can be used to enumerate jobs asynchronously or sy
 115        /// <remarks>This method returns immediately; the jobs are retrieved from the Batch service only when the collec
 116        /// Retrieval is non-atomic; jobs are retrieved in pages during enumeration of the collection.</remarks>
 117        public IPagedEnumerable<CloudJob> ListJobs(DetailLevel detailLevel = null, IEnumerable<BatchClientBehavior> addi
 118        {
 119            // set up behavior manager
 2120            BehaviorManager bhMgr = new BehaviorManager(this.CustomBehaviors, additionalBehaviors);
 121
 2122            IPagedEnumerable<CloudJob> enumerable = ListJobsImpl(bhMgr, detailLevel);
 123
 2124            return enumerable;
 125        }
 126
 127        internal async System.Threading.Tasks.Task<CloudJob> GetJobAsyncImpl(string jobId, BehaviorManager bhMgr, Cancel
 128        {
 27129            System.Threading.Tasks.Task<AzureOperationResponse<Models.CloudJob, Models.JobGetHeaders>> asyncTask = this.
 130
 27131            AzureOperationResponse<Models.CloudJob, Models.JobGetHeaders> response = await asyncTask.ConfigureAwait(cont
 132
 133            // extract job from response
 15134            Models.CloudJob protoJob = response.Body;
 135
 136            // convert to bound object layer equiv
 15137            CloudJob openedJob = new CloudJob(this.ParentBatchClient, protoJob, bhMgr.BaseBehaviors);
 138
 15139            return openedJob;
 15140        }
 141
 142        /// <summary>
 143        /// Gets the specified <see cref="CloudJob"/>.
 144        /// </summary>
 145        /// <param name="jobId">The id of the job to get.</param>
 146        /// <param name="detailLevel">A <see cref="DetailLevel"/> used for controlling which properties are retrieved fr
 147        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 148        /// <param name="cancellationToken">A <see cref="CancellationToken"/> for controlling the lifetime of the asynch
 149        /// <returns>A <see cref="CloudJob"/> containing information about the specified Azure Batch job.</returns>
 150        /// <remarks>The get job operation runs asynchronously.</remarks>
 151        public async System.Threading.Tasks.Task<CloudJob> GetJobAsync(
 152            string jobId,
 153            DetailLevel detailLevel = null,
 154            IEnumerable<BatchClientBehavior> additionalBehaviors = null,
 155            CancellationToken cancellationToken = default(CancellationToken))
 156        {
 157            // set up behavior manager
 27158            BehaviorManager bhMgr = new BehaviorManager(this.CustomBehaviors, additionalBehaviors, detailLevel);
 159
 27160            System.Threading.Tasks.Task<CloudJob> asyncTask = GetJobAsyncImpl(jobId, bhMgr, cancellationToken);
 161
 27162            CloudJob openedJob = await asyncTask.ConfigureAwait(continueOnCapturedContext: false);
 163
 15164            return openedJob;
 15165        }
 166
 167        /// <summary>
 168        /// Gets the specified <see cref="CloudJob"/>.
 169        /// </summary>
 170        /// <param name="jobId">The id of the job to get.</param>
 171        /// <param name="detailLevel">A <see cref="DetailLevel"/> used for controlling which properties are retrieved fr
 172        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 173        /// <returns>A <see cref="CloudJob"/> containing information about the specified Azure Batch job.</returns>
 174        /// <remarks>This is a blocking operation. For a non-blocking equivalent, see <see cref="GetJobAsync"/>.</remark
 175        public CloudJob GetJob(string jobId, DetailLevel detailLevel = null, IEnumerable<BatchClientBehavior> additional
 176        {
 16177            Task<CloudJob> asyncTask = GetJobAsync(jobId, detailLevel, additionalBehaviors);
 16178            CloudJob newJob = asyncTask.WaitAndUnaggregateException(this.CustomBehaviors, additionalBehaviors);
 179
 12180            return newJob;
 181        }
 182
 183        internal async Task<TaskCounts> GetJobTaskCountsAsyncImpl(string jobId, BehaviorManager bhMgr, CancellationToken
 184        {
 1185            AzureOperationResponse<Models.TaskCounts, Models.JobGetTaskCountsHeaders> response = await this.ParentBatchC
 1186                jobId,
 1187                bhMgr,
 1188                cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
 0189            Models.TaskCounts protoTaskCounts = response.Body;
 0190            TaskCounts result = new TaskCounts(protoTaskCounts);
 191
 0192            return result;
 0193        }
 194
 195        /// <summary>
 196        /// Gets the task counts for the specified job.
 197        /// </summary>
 198        /// <param name="jobId">The id of the job.</param>
 199        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 200        /// <param name="cancellationToken">A <see cref="CancellationToken"/> for controlling the lifetime of the asynch
 201        /// <remarks>The get job task counts operation runs asynchronously.</remarks>
 202        /// <returns>A <see cref="TaskCounts"/> object containing the task counts for the job.</returns>
 203        public async Task<TaskCounts> GetJobTaskCountsAsync(
 204            string jobId,
 205            IEnumerable<BatchClientBehavior> additionalBehaviors = null,
 206            CancellationToken cancellationToken = default(CancellationToken))
 207        {
 208            // set up behavior manager
 1209            BehaviorManager bhMgr = new BehaviorManager(this.CustomBehaviors, additionalBehaviors, detailLevel: null);
 1210            TaskCounts counts = await GetJobTaskCountsAsyncImpl(jobId, bhMgr, cancellationToken).ConfigureAwait(continue
 211
 0212            return counts;
 0213        }
 214
 215        /// <summary>
 216        /// Gets the task counts for the specified job.
 217        /// </summary>
 218        /// <param name="jobId">The id of the job.</param>
 219        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 220        /// <returns>A <see cref="TaskCounts"/> object containing the task counts for the job.</returns>
 221        /// <remarks>This is a blocking operation. For a non-blocking equivalent, see <see cref="GetJobTaskCountsAsync"/
 222        public TaskCounts GetJobTaskCounts(string jobId, IEnumerable<BatchClientBehavior> additionalBehaviors = null)
 223        {
 0224            TaskCounts result = GetJobTaskCountsAsync(jobId, additionalBehaviors).WaitAndUnaggregateException(this.Custo
 0225            return result;
 226        }
 227
 228        /// <summary>
 229        /// Enables the specified job, allowing new tasks to run.
 230        /// </summary>
 231        /// <param name="jobId">The id of the job.</param>
 232        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 233        /// <param name="cancellationToken">A <see cref="CancellationToken"/> for controlling the lifetime of the asynch
 234        /// <returns>A <see cref="System.Threading.Tasks.Task"/> that represents the asynchronous operation.</returns>
 235        /// <remarks>The enable operation runs asynchronously.</remarks>
 236        public async System.Threading.Tasks.Task EnableJobAsync(string jobId, IEnumerable<BatchClientBehavior> additiona
 237        {
 238            // set up behavior manager
 1239            BehaviorManager bhMgr = new BehaviorManager(this.CustomBehaviors, additionalBehaviors);
 240
 1241            Task asyncTask = this.ParentBatchClient.ProtocolLayer.EnableJob(jobId, bhMgr, cancellationToken);
 242
 1243            await asyncTask.ConfigureAwait(continueOnCapturedContext: false);
 0244        }
 245
 246        /// <summary>
 247        /// Enables the specified job, allowing new tasks to run.
 248        /// </summary>
 249        /// <param name="jobId">The id of the job.</param>
 250        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 251        /// <remarks>This is a blocking operation. For a non-blocking equivalent, see <see cref="EnableJobAsync"/>.</rem
 252        public void EnableJob(string jobId, IEnumerable<BatchClientBehavior> additionalBehaviors = null)
 253        {
 0254            Task asyncTask = EnableJobAsync(jobId, additionalBehaviors);
 0255            asyncTask.WaitAndUnaggregateException(this.CustomBehaviors, additionalBehaviors);
 0256        }
 257
 258        /// <summary>
 259        /// Disables the specified job.  Disabled jobs do not run new tasks, but may be re-enabled later.
 260        /// </summary>
 261        /// <param name="jobId">The id of the job.</param>
 262        /// <param name="disableJobOption">Specifies what to do with active tasks associated with the job.</param>
 263        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 264        /// <param name="cancellationToken">A <see cref="CancellationToken"/> for controlling the lifetime of the asynch
 265        /// <returns>A <see cref="System.Threading.Tasks.Task"/> that represents the asynchronous operation.</returns>
 266        /// <remarks>The disable operation runs asynchronously.</remarks>
 267        public async System.Threading.Tasks.Task DisableJobAsync(
 268            string jobId,
 269            Common.DisableJobOption disableJobOption,
 270            IEnumerable<BatchClientBehavior> additionalBehaviors = null,
 271            CancellationToken cancellationToken = default(CancellationToken))
 272        {
 273            // set up behavior manager
 1274            BehaviorManager bhMgr = new BehaviorManager(this.CustomBehaviors, additionalBehaviors);
 275
 1276            Task asyncTask = this.ParentBatchClient.ProtocolLayer.DisableJob(jobId, disableJobOption, bhMgr, cancellatio
 277
 1278            await asyncTask.ConfigureAwait(continueOnCapturedContext: false);
 0279        }
 280
 281        /// <summary>
 282        /// Disables the specified job.  Disabled jobs do not run new tasks, but may be re-enabled later.
 283        /// </summary>
 284        /// <param name="jobId">The id of the job.</param>
 285        /// <param name="disableJobOption">Specifies what to do with active tasks associated with the job.</param>
 286        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 287        /// <remarks>This is a blocking operation. For a non-blocking equivalent, see <see cref="DisableJobAsync"/>.</re
 288        public void DisableJob(string jobId, Common.DisableJobOption disableJobOption, IEnumerable<BatchClientBehavior> 
 289        {
 0290            Task asyncTask = DisableJobAsync(jobId, disableJobOption, additionalBehaviors);
 0291            asyncTask.WaitAndUnaggregateException(this.CustomBehaviors, additionalBehaviors);
 0292        }
 293
 294        /// <summary>
 295        /// Terminates the specified job, marking it as completed.
 296        /// </summary>
 297        /// <param name="jobId">The id of the job.</param>
 298        /// <param name="terminateReason">The text you want to appear as the job's <see cref="JobExecutionInformation.Te
 299        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 300        /// <param name="cancellationToken">A <see cref="CancellationToken"/> for controlling the lifetime of the asynch
 301        /// <returns>A <see cref="System.Threading.Tasks.Task"/> object that represents the asynchronous operation.</ret
 302        /// <remarks>The terminate operation runs asynchronously.</remarks>
 303        public async System.Threading.Tasks.Task TerminateJobAsync(
 304            string jobId,
 305            string terminateReason = null,
 306            IEnumerable<BatchClientBehavior> additionalBehaviors = null,
 307            CancellationToken cancellationToken = default(CancellationToken))
 308        {
 309            // set up behavior manager
 1310            BehaviorManager bhMgr = new BehaviorManager(this.CustomBehaviors, additionalBehaviors);
 311
 1312            Task asyncTask = this.ParentBatchClient.ProtocolLayer.TerminateJob(jobId, terminateReason, bhMgr, cancellati
 313
 1314            await asyncTask.ConfigureAwait(continueOnCapturedContext: false);
 0315        }
 316
 317        /// <summary>
 318        /// Terminates the specified job, marking it as completed.
 319        /// </summary>
 320        /// <param name="jobId">The id of the job.</param>
 321        /// <param name="terminateReason">The text you want to appear as the job's <see cref="JobExecutionInformation.Te
 322        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 323        /// <remarks>This is a blocking operation. For a non-blocking equivalent, see <see cref="TerminateJobAsync"/>.</
 324        public void TerminateJob(string jobId, string terminateReason = null, IEnumerable<BatchClientBehavior> additiona
 325        {
 0326            Task asyncTask = TerminateJobAsync(jobId, terminateReason, additionalBehaviors);
 0327            asyncTask.WaitAndUnaggregateException(this.CustomBehaviors, additionalBehaviors);
 0328        }
 329
 330        /// <summary>
 331        /// Deletes the specified job.
 332        /// </summary>
 333        /// <param name="jobId">The id of the job.</param>
 334        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 335        /// <param name="cancellationToken">A <see cref="CancellationToken"/> for controlling the lifetime of the asynch
 336        /// <returns>A <see cref="System.Threading.Tasks.Task"/> that represents the asynchronous operation.</returns>
 337        /// <remarks>
 338        /// <para>The delete operation requests that the job be deleted.  The request puts the job in the <see cref="Com
 339        /// The Batch service will stop any running tasks and perform the actual job deletion without any further client
 340        /// <para>The delete operation runs asynchronously.</para>
 341        /// </remarks>
 342        public async System.Threading.Tasks.Task DeleteJobAsync(string jobId, IEnumerable<BatchClientBehavior> additiona
 343        {
 344            // set up behavior manager
 1345            BehaviorManager bhMgr = new BehaviorManager(this.CustomBehaviors, additionalBehaviors);
 346
 1347            Task asyncTask = this.ParentBatchClient.ProtocolLayer.DeleteJob(jobId, bhMgr, cancellationToken);
 348
 1349            await asyncTask.ConfigureAwait(continueOnCapturedContext: false);
 0350        }
 351
 352        /// <summary>
 353        /// Deletes the specified job.
 354        /// </summary>
 355        /// <param name="jobId">The id of the job.</param>
 356        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 357        /// <remarks>
 358        /// <para>The delete operation requests that the job be deleted.  The request puts the job in the <see cref="Com
 359        /// The Batch service will stop any running tasks and perform the actual job deletion without any further client
 360        /// <para>This is a blocking operation. For a non-blocking equivalent, see <see cref="DeleteJobAsync"/>.</para>
 361        /// </remarks>
 362        public void DeleteJob(string jobId, IEnumerable<BatchClientBehavior> additionalBehaviors = null)
 363        {
 0364            Task asyncTask = DeleteJobAsync(jobId, additionalBehaviors);
 0365            asyncTask.WaitAndUnaggregateException(this.CustomBehaviors, additionalBehaviors);
 0366        }
 367
 368        internal IPagedEnumerable<CloudTask> ListTasksImpl(string jobId, BehaviorManager bhMgr, DetailLevel detailLevel)
 369        {
 6370            PagedEnumerable<CloudTask> enumerable = new PagedEnumerable<CloudTask>( // the lamda will be the enumerator 
 6371                () =>
 6372                {
 6373                    // here is the actual strongly typed enumerator
 12374                    AsyncListTasksEnumerator typedEnumerator = new AsyncListTasksEnumerator(this, jobId, bhMgr, detailLe
 6375
 6376                    // here is the base
 6377                    PagedEnumeratorBase<CloudTask> enumeratorBase = typedEnumerator;
 6378
 12379                    return enumeratorBase;
 6380                });
 381
 6382            return enumerable;
 383        }
 384
 385
 386        /// <summary>
 387        /// Enumerates the <see cref="CloudTask">tasks</see> of the specified job.
 388        /// </summary>
 389        /// <param name="jobId">The id of the job.</param>
 390        /// <param name="detailLevel">A <see cref="DetailLevel"/> used for filtering the list and for controlling which 
 391        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 392        /// <returns>An <see cref="IPagedEnumerable{CloudTask}"/> that can be used to enumerate tasks asynchronously or 
 393        /// <remarks>This method returns immediately; the tasks are retrieved from the Batch service only when the colle
 394        /// Retrieval is non-atomic; tasks are retrieved in pages during enumeration of the collection.</remarks>
 395        public IPagedEnumerable<CloudTask> ListTasks(
 396                                                        string jobId,
 397                                                        DetailLevel detailLevel = null,
 398                                                        IEnumerable<BatchClientBehavior> additionalBehaviors = null)
 399        {
 400            // set up behavior manager
 3401            BehaviorManager bhMgr = new BehaviorManager(this.CustomBehaviors, additionalBehaviors);
 402
 403            // get the enumerable
 3404            IPagedEnumerable<CloudTask> enumerable = ListTasksImpl(jobId, bhMgr, detailLevel);
 405
 3406            return enumerable;
 407        }
 408
 409        internal async System.Threading.Tasks.Task<CloudTask> GetTaskAsyncImpl(
 410                                                                    string jobId,
 411                                                                    string taskId,
 412                                                                    BehaviorManager bhMgr,
 413                                                                    CancellationToken cancellationToken)
 414        {
 3415            Task<AzureOperationResponse<Models.CloudTask, Models.TaskGetHeaders>> asyncTask =
 3416                this.ParentBatchClient.ProtocolLayer.GetTask(
 3417                    jobId,
 3418                    taskId,
 3419                    bhMgr,
 3420                    cancellationToken);
 421
 3422            AzureOperationResponse<Models.CloudTask, Models.TaskGetHeaders> response = await asyncTask.ConfigureAwait(co
 423
 424            // extract protocol task
 2425            Models.CloudTask protoTask = response.Body;
 426
 427            // bind CloudTask to protocol task
 2428            CloudTask newTask = new CloudTask(this.ParentBatchClient, jobId, protoTask, bhMgr.BaseBehaviors);
 429
 2430            return newTask;
 2431        }
 432
 433        /// <summary>
 434        /// Gets the specified <see cref="CloudTask"/>.
 435        /// </summary>
 436        /// <param name="jobId">The id of the job from which to get the task.</param>
 437        /// <param name="taskId">The id of the task to get.</param>
 438        /// <param name="detailLevel">A <see cref="DetailLevel"/> used for controlling which properties are retrieved fr
 439        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 440        /// <param name="cancellationToken">A <see cref="CancellationToken"/> for controlling the lifetime of the asynch
 441        /// <returns>A <see cref="CloudTask"/> containing information about the specified Azure Batch task.</returns>
 442        /// <remarks>The get task operation runs asynchronously.</remarks>
 443        public System.Threading.Tasks.Task<CloudTask> GetTaskAsync(
 444            string jobId,
 445            string taskId,
 446            DetailLevel detailLevel = null,
 447            IEnumerable<BatchClientBehavior> additionalBehaviors = null,
 448            CancellationToken cancellationToken = default(CancellationToken))
 449        {
 450            // set up behavior manager
 3451            BehaviorManager bhMgr = new BehaviorManager(this.CustomBehaviors, additionalBehaviors, detailLevel);
 452
 3453            System.Threading.Tasks.Task<CloudTask> asyncTask = GetTaskAsyncImpl(jobId, taskId, bhMgr, cancellationToken)
 454
 3455            return asyncTask;
 456        }
 457
 458        /// <summary>
 459        /// Gets the specified <see cref="CloudTask"/>.
 460        /// </summary>
 461        /// <param name="jobId">The id of the job from which to get the task.</param>
 462        /// <param name="taskId">The id of the task to get.</param>
 463        /// <param name="detailLevel">A <see cref="DetailLevel"/> used for controlling which properties are retrieved fr
 464        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 465        /// <returns>A <see cref="CloudTask"/> containing information about the specified Azure Batch task.</returns>
 466        /// <remarks>This is a blocking operation. For a non-blocking equivalent, see <see cref="GetTaskAsync"/>.</remar
 467        public CloudTask GetTask(string jobId, string taskId, DetailLevel detailLevel = null, IEnumerable<BatchClientBeh
 468        {
 2469            Task<CloudTask> asyncTask = GetTaskAsync(jobId, taskId, detailLevel, additionalBehaviors);
 2470            CloudTask newTask = asyncTask.WaitAndUnaggregateException(this.CustomBehaviors, additionalBehaviors);
 471
 2472            return newTask;
 473        }
 474
 475        /// <summary>
 476        /// Enumerates the <see cref="SubtaskInformation">subtask information</see> of the specified task.
 477        /// </summary>
 478        /// <param name="jobId">The id of the job.</param>
 479        /// <param name="taskId">The id of the task to get.</param>
 480        /// <param name="detailLevel">A <see cref="DetailLevel"/> used for filtering the list and for controlling which 
 481        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 482        /// <returns>An <see cref="IPagedEnumerable{SubtaskInformation}"/> that can be used to enumerate subtasks asynch
 483        /// <remarks>This method returns immediately; the tasks are retrieved from the Batch service only when the colle
 484        /// Retrieval is non-atomic; tasks are retrieved in pages during enumeration of the collection.</remarks>
 485        public IPagedEnumerable<SubtaskInformation> ListSubtasks(string jobId,
 486                                                        string taskId,
 487                                                        DetailLevel detailLevel = null,
 488                                                        IEnumerable<BatchClientBehavior> additionalBehaviors = null)
 489        {
 490            // set up behavior manager
 1491            BehaviorManager bhMgr = new BehaviorManager(this.CustomBehaviors, additionalBehaviors);
 492
 493            // get the enumerable
 1494            IPagedEnumerable<SubtaskInformation> enumerable = ListSubtasksImpl(jobId, taskId, bhMgr, detailLevel);
 495
 1496            return enumerable;
 497        }
 498
 499        internal async System.Threading.Tasks.Task AddTaskAsyncImpl(
 500            string jobId,
 501            CloudTask taskToAdd,
 502            BehaviorManager bhMgr,
 503            CancellationToken cancellationToken,
 504            ConcurrentDictionary<Type, IFileStagingArtifact> allFileStagingArtifacts = null)
 505        {
 506            // only our implementation can be used to GetProtocolObject.
 8507            CloudTask implTask = taskToAdd;
 508
 8509            if (null == implTask)
 510            {
 0511                throw new ArgumentOutOfRangeException("taskToAdd");
 512            }
 513
 514            // ensure we have artifacts
 8515            if (null == allFileStagingArtifacts)
 516            {
 1517                allFileStagingArtifacts = new ConcurrentDictionary<Type, IFileStagingArtifact>();
 518            }
 519
 520            // start file staging
 8521            System.Threading.Tasks.Task stagingTask = implTask.StageFilesAsync(allFileStagingArtifacts);
 522
 523            // wait for the files to be staged
 8524            await stagingTask.ConfigureAwait(continueOnCapturedContext: false);
 525
 526            // get the CloudTask to convert itself to a protocol object
 8527            Models.TaskAddParameter protoTask = implTask.GetTransportObject();
 8528            implTask.Freeze(); //Mark the underlying task readonly
 529
 530            // start the AddTask request
 8531            System.Threading.Tasks.Task asyncTask = this.ParentBatchClient.ProtocolLayer.AddTask(jobId, protoTask, bhMgr
 532
 8533            await asyncTask.ConfigureAwait(continueOnCapturedContext: false);
 7534        }
 535
 536        /// <summary>
 537        /// Adds a single task to a job.  To add multiple tasks,
 538        /// use <see cref="AddTaskAsync(string,IEnumerable{CloudTask},BatchClientParallelOptions,ConcurrentBag{Concurren
 539        /// </summary>
 540        /// <param name="jobId">The id of the job to which to add the task.</param>
 541        /// <param name="taskToAdd">The <see cref="CloudTask"/> to add.</param>
 542        /// <param name="allFileStagingArtifacts">An optional collection to customize and receive information about the 
 543        /// For more information see <see cref="IFileStagingArtifact"/>.</param>
 544        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 545        /// <param name="cancellationToken">A <see cref="CancellationToken"/> for controlling the lifetime of the asynch
 546        /// <returns>A <see cref="System.Threading.Tasks.Task"/> object that represents the asynchronous operation.</ret
 547        /// <remarks>
 548        /// <para>Each call to this method incurs a request to the Batch service. Therefore, using this method to add
 549        /// multiple tasks is less efficient than using a bulk add method, and can incur HTTP connection restrictions.
 550        /// If you are performing many of these operations in parallel and are seeing client side timeouts, please see
 551        /// http://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.defaultconnectionlimit%28v=vs.110%29.
 552        /// or use the multiple-task overload of AddTaskAsync.</para>
 553        /// <para>The add task operation runs asynchronously.</para>
 554        /// </remarks>
 555        public System.Threading.Tasks.Task AddTaskAsync(
 556            string jobId,
 557            CloudTask taskToAdd,
 558            ConcurrentDictionary<Type, IFileStagingArtifact> allFileStagingArtifacts = null,
 559            IEnumerable<BatchClientBehavior> additionalBehaviors = null,
 560            CancellationToken cancellationToken = default(CancellationToken))
 561        {
 562            // set up behavior manager
 1563            BehaviorManager bhMgr = new BehaviorManager(this.CustomBehaviors, additionalBehaviors);
 564
 1565            System.Threading.Tasks.Task asyncTask = AddTaskAsyncImpl(jobId, taskToAdd, bhMgr, cancellationToken, allFile
 566
 1567            return asyncTask;
 568        }
 569
 570        /// <summary>
 571        /// Adds a single task to a job.  To add multiple tasks,
 572        /// use <see cref="AddTask(string,IEnumerable{CloudTask},BatchClientParallelOptions,ConcurrentBag{ConcurrentDict
 573        /// </summary>
 574        /// <param name="jobId">The id of the job to which to add the task.</param>
 575        /// <param name="taskToAdd">The <see cref="CloudTask"/> to add.</param>
 576        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 577        /// <returns>A collection of information about the file staging process (see <see cref="CloudTask.FilesToStage"/
 578        /// For more information see <see cref="IFileStagingArtifact"/>.</returns>
 579        /// <remarks>
 580        /// <para>Each call to this method incurs a request to the Batch service. Therefore, using this method to add
 581        /// multiple tasks is less efficient than using a bulk add method, and can incur HTTP connection restrictions.
 582        /// If you are performing many of these operations in parallel and are seeing client side timeouts, please see
 583        /// http://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.defaultconnectionlimit%28v=vs.110%29.
 584        /// or use the multiple-task overload of AddTask.</para>
 585        /// <para>This is a blocking operation. For a non-blocking equivalent, see <see cref="AddTaskAsync(string, Cloud
 586        /// </remarks>
 587        public ConcurrentDictionary<Type, IFileStagingArtifact> AddTask(string jobId, CloudTask taskToAdd, IEnumerable<B
 588        {
 0589            ConcurrentDictionary<Type, IFileStagingArtifact> artifacts = new ConcurrentDictionary<Type,IFileStagingArtif
 590
 0591            Task asyncTask = this.AddTaskAsync(jobId, taskToAdd, artifacts, additionalBehaviors);
 592
 0593            asyncTask.WaitAndUnaggregateException(this.CustomBehaviors, additionalBehaviors);
 594
 0595            return artifacts;
 596        }
 597
 598        internal IPagedEnumerable<NodeFile> ListNodeFilesImpl(
 599                                                        string jobId,
 600                                                        string taskId,
 601                                                        bool? recursive,
 602                                                        BehaviorManager bhMgr,
 603                                                        DetailLevel detailLevel)
 604        {
 1605            PagedEnumerable<NodeFile> enumerable = new PagedEnumerable<NodeFile>( // the lamda will be the enumerator fa
 1606                () =>
 1607                {
 1608                    // here is the actual strongly typed enumerator
 2609                    AsyncListNodeFilesByTaskEnumerator typedEnumerator = new AsyncListNodeFilesByTaskEnumerator(this, jo
 1610
 1611                    // here is the base
 1612                    PagedEnumeratorBase<NodeFile> enumeratorBase = typedEnumerator;
 1613
 2614                    return enumeratorBase;
 1615                });
 616
 1617            return enumerable;
 618        }
 619
 620        internal IPagedEnumerable<SubtaskInformation> ListSubtasksImpl(
 621                                                        string jobId,
 622                                                        string taskId,
 623                                                        BehaviorManager bhMgr,
 624                                                        DetailLevel detailLevel)
 625        {
 1626            PagedEnumerable<SubtaskInformation> enumerable = new PagedEnumerable<SubtaskInformation>( // the lamda will 
 1627                () =>
 1628                {
 1629                    // here is the actual strongly typed enumerator
 2630                    AsyncListSubtasksEnumerator typedEnumerator = new AsyncListSubtasksEnumerator(this, jobId, taskId, b
 1631
 1632                    // here is the base
 1633                    PagedEnumeratorBase<SubtaskInformation> enumeratorBase = typedEnumerator;
 1634
 2635                    return enumeratorBase;
 1636                });
 637
 1638            return enumerable;
 639        }
 640
 641        /// <summary>
 642        /// Enumerates the <see cref="NodeFile">NodeFiles</see> in the specified task's directory on its compute node.
 643        /// </summary>
 644        /// <param name="jobId">The id of the job.</param>
 645        /// <param name="taskId">The id of the task.</param>
 646        /// <param name="recursive">If true, performs a recursive list of all files of the task. If false, returns only 
 647        /// <param name="detailLevel">A <see cref="DetailLevel"/> used for filtering the list and for controlling which 
 648        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 649        /// <returns>An <see cref="IPagedEnumerable{NodeFile}"/> that can be used to enumerate files asynchronously or s
 650        /// <remarks>This method returns immediately; the file data is retrieved from the Batch service only when the co
 651        /// Retrieval is non-atomic; file data is retrieved in pages during enumeration of the collection.</remarks>
 652        public IPagedEnumerable<NodeFile> ListNodeFiles(
 653                                                        string jobId,
 654                                                        string taskId,
 655                                                        bool? recursive = null,
 656                                                        DetailLevel detailLevel = null,
 657                                                        IEnumerable<BatchClientBehavior> additionalBehaviors = null)
 658        {
 659            // set up behavior manager
 1660            BehaviorManager bhMgr = new BehaviorManager(this.CustomBehaviors, additionalBehaviors);
 661
 662            // get the enumerable
 1663            IPagedEnumerable<NodeFile> enumerable = this.ListNodeFilesImpl(jobId, taskId, recursive, bhMgr, detailLevel)
 664
 1665            return enumerable;
 666        }
 667
 668        /// <summary>
 669        /// Terminates the specified task.
 670        /// </summary>
 671        /// <param name="jobId">The id of the job containing the task.</param>
 672        /// <param name="taskId">The id of the task.</param>
 673        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 674        /// <param name="cancellationToken">A <see cref="CancellationToken"/> for controlling the lifetime of the asynch
 675        /// <returns>A <see cref="System.Threading.Tasks.Task"/> that represents the asynchronous operation.</returns>
 676        /// <remarks>The terminate operation runs asynchronously.</remarks>
 677        public System.Threading.Tasks.Task TerminateTaskAsync(
 678            string jobId,
 679            string taskId,
 680            IEnumerable<BatchClientBehavior> additionalBehaviors = null,
 681            CancellationToken cancellationToken = default(CancellationToken))
 682        {
 683            // set up behavior manager
 1684            BehaviorManager bhMgr = new BehaviorManager(this.CustomBehaviors, additionalBehaviors);
 685
 1686            System.Threading.Tasks.Task asyncTask = this.ParentBatchClient.ProtocolLayer.TerminateTask(jobId, taskId, bh
 687
 1688            return asyncTask;
 689        }
 690
 691        /// <summary>
 692        /// Terminates the specified task.
 693        /// </summary>
 694        /// <param name="jobId">The id of the job containing the task.</param>
 695        /// <param name="taskId">The id of the task.</param>
 696        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 697        /// <returns>A <see cref="System.Threading.Tasks.Task"/> that represents the asynchronous operation.</returns>
 698        /// <remarks>This is a blocking operation.  For a non-blocking equivalent, see <see cref="TerminateTaskAsync"/>.
 699        public void TerminateTask(
 700            string jobId,
 701            string taskId,
 702            IEnumerable<BatchClientBehavior> additionalBehaviors = null)
 703        {
 0704            Task asyncTask = TerminateTaskAsync(jobId, taskId, additionalBehaviors);
 0705            asyncTask.WaitAndUnaggregateException(this.CustomBehaviors, additionalBehaviors);
 706
 0707        }
 708
 709        /// <summary>
 710        /// Deletes the specified task.
 711        /// </summary>
 712        /// <param name="jobId">The id of the job containing the task.</param>
 713        /// <param name="taskId">The id of the task.</param>
 714        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 715        /// <param name="cancellationToken">A <see cref="CancellationToken"/> for controlling the lifetime of the asynch
 716        /// <returns>A <see cref="System.Threading.Tasks.Task"/> that represents the asynchronous operation.</returns>
 717        /// <remarks>The delete operation runs asynchronously.</remarks>
 718        public System.Threading.Tasks.Task DeleteTaskAsync(
 719            string jobId,
 720            string taskId,
 721            IEnumerable<BatchClientBehavior> additionalBehaviors = null,
 722            CancellationToken cancellationToken = default(CancellationToken))
 723        {
 724            // set up behavior manager
 1725            BehaviorManager bhMgr = new BehaviorManager(this.CustomBehaviors, additionalBehaviors);
 726
 1727            System.Threading.Tasks.Task asyncTask = this.ParentBatchClient.ProtocolLayer.DeleteTask(jobId, taskId, bhMgr
 728
 1729            return asyncTask;
 730        }
 731
 732        /// <summary>
 733        /// Deletes the specified task.
 734        /// </summary>
 735        /// <param name="jobId">The id of the job containing the task.</param>
 736        /// <param name="taskId">The id of the task.</param>
 737        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 738        /// <remarks>This is a blocking operation.  For a non-blocking equivalent, see <see cref="DeleteTaskAsync"/>.</r
 739        public void DeleteTask(
 740            string jobId,
 741            string taskId,
 742            IEnumerable<BatchClientBehavior> additionalBehaviors = null)
 743        {
 0744            Task asyncTask = DeleteTaskAsync(jobId, taskId, additionalBehaviors);
 0745            asyncTask.WaitAndUnaggregateException(this.CustomBehaviors, additionalBehaviors);
 0746        }
 747
 748        /// <summary>
 749        /// Reactivates a task, allowing it to run again even if its retry count has been exhausted.
 750        /// </summary>
 751        /// <param name="jobId">The id of the job containing the task.</param>
 752        /// <param name="taskId">The id of the task.</param>
 753        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 754        /// <param name="cancellationToken">A <see cref="CancellationToken"/> for controlling the lifetime of the asynch
 755        /// <returns>A <see cref="System.Threading.Tasks.Task"/> that represents the asynchronous operation.</returns>
 756        /// <remarks>
 757        /// <para>
 758        /// Reactivation makes a task eligible to be retried again up to its maximum retry count.
 759        /// </para>
 760        /// <para>
 761        /// Additionally, this will fail if the job is in the <see cref="JobState.Completed"/> or <see cref="JobState.Te
 762        /// This is a blocking operation. For a non-blocking equivalent, see <see cref="ReactivateTaskAsync"/>.
 763        /// </para>
 764        /// <para>
 765        /// The reactivate operation runs asynchronously.
 766        /// </para>
 767        /// </remarks>
 768        public System.Threading.Tasks.Task ReactivateTaskAsync(
 769            string jobId,
 770            string taskId,
 771            IEnumerable<BatchClientBehavior> additionalBehaviors = null,
 772            CancellationToken cancellationToken = default(CancellationToken))
 773        {
 774            // set up behavior manager
 1775            BehaviorManager bhMgr = new BehaviorManager(this.CustomBehaviors, additionalBehaviors);
 776
 1777            System.Threading.Tasks.Task asyncTask = this.ParentBatchClient.ProtocolLayer.ReactivateTask(jobId, taskId, b
 778
 1779            return asyncTask;
 780        }
 781
 782        /// <summary>
 783        /// Reactivates a task, allowing it to run again even if its retry count has been exhausted.
 784        /// </summary>
 785        /// <param name="jobId">The id of the job containing the task.</param>
 786        /// <param name="taskId">The id of the task.</param>
 787        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 788        /// <remarks>
 789        /// <para>
 790        /// Reactivation makes a task eligible to be retried again up to its maximum retry count.
 791        /// </para>
 792        /// <para>
 793        /// This operation will fail for tasks that are not completed or that previously completed successfully (with an
 794        /// </para>
 795        /// <para>
 796        /// Additionally, this will fail if the job is in the <see cref="JobState.Completed"/> or <see cref="JobState.Te
 797        /// This is a blocking operation. For a non-blocking equivalent, see <see cref="ReactivateTaskAsync"/>.
 798        /// </para>
 799        /// </remarks>
 800        public void ReactivateTask(
 801            string jobId,
 802            string taskId,
 803            IEnumerable<BatchClientBehavior> additionalBehaviors = null)
 804        {
 0805            Task asyncTask = ReactivateTaskAsync(jobId, taskId, additionalBehaviors);
 0806            asyncTask.WaitAndUnaggregateException(this.CustomBehaviors, additionalBehaviors);
 0807        }
 808
 809        internal async System.Threading.Tasks.Task<NodeFile> GetNodeFileAsyncImpl(
 810            string jobId,
 811            string taskId,
 812            string filePath,
 813            BehaviorManager bhMgr,
 814            CancellationToken cancellationToken)
 815        {
 4816            var getNodeFilePropertiesTask = await this.ParentBatchClient.ProtocolLayer.GetNodeFilePropertiesByTask(
 4817                jobId,
 4818                taskId,
 4819                filePath,
 4820                bhMgr,
 4821                cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
 822
 3823            Models.NodeFile file = getNodeFilePropertiesTask.Body;
 824
 825            // wrap protocol object
 3826            NodeFile wrapped = new TaskFile(this, jobId, taskId, file, bhMgr.BaseBehaviors);
 827
 3828            return wrapped;
 3829        }
 830
 831        /// <summary>
 832        /// Gets the specified <see cref="NodeFile"/> from the specified task's directory on its compute node.
 833        /// </summary>
 834        /// <param name="jobId">The id of the job containing the task.</param>
 835        /// <param name="taskId">The id of the task.</param>
 836        /// <param name="filePath">The path of the file to retrieve.</param>
 837        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 838        /// <param name="cancellationToken">A <see cref="CancellationToken"/> for controlling the lifetime of the asynch
 839        /// <returns>A <see cref="NodeFile"/> representing the specified file.</returns>
 840        /// <remarks>The get file operation runs asynchronously.</remarks>
 841        public System.Threading.Tasks.Task<NodeFile> GetNodeFileAsync(
 842            string jobId,
 843            string taskId,
 844            string filePath,
 845            IEnumerable<BatchClientBehavior> additionalBehaviors = null,
 846            CancellationToken cancellationToken = default(CancellationToken))
 847        {
 848            // set up behavior manager
 4849            BehaviorManager bhMgr = new BehaviorManager(this.CustomBehaviors, additionalBehaviors);
 850
 4851            System.Threading.Tasks.Task<NodeFile> asyncTask = this.GetNodeFileAsyncImpl(jobId, taskId, filePath, bhMgr, 
 852
 4853            return asyncTask;
 854        }
 855
 856        /// <summary>
 857        /// Gets the specified <see cref="NodeFile"/> from the specified task's directory on its compute node.
 858        /// </summary>
 859        /// <param name="jobId">The id of the job containing the task.</param>
 860        /// <param name="taskId">The id of the task.</param>
 861        /// <param name="filePath">The path of the file to retrieve.</param>
 862        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 863        /// <returns>A <see cref="NodeFile"/> representing the specified file.</returns>
 864        /// <remarks>This is a blocking operation.  For a non-blocking equivalent, see <see cref="GetNodeFileAsync"/>.</
 865        public NodeFile GetNodeFile(
 866            string jobId,
 867            string taskId,
 868            string filePath,
 869            IEnumerable<BatchClientBehavior> additionalBehaviors = null)
 870        {
 0871            Task<NodeFile> asyncTask = this.GetNodeFileAsync(jobId, taskId, filePath, additionalBehaviors);
 0872            NodeFile file = asyncTask.WaitAndUnaggregateException(this.CustomBehaviors, additionalBehaviors);
 0873            return file;
 874        }
 875
 876        internal async Task CopyNodeFileContentToStreamAsyncImpl(
 877            string jobId,
 878            string taskId,
 879            string filePath,
 880            Stream stream,
 881            GetFileRequestByteRange byteRange,
 882            BehaviorManager bhMgr,
 883            CancellationToken cancellationToken)
 884        {
 2885            await this.ParentBatchClient.ProtocolLayer.GetNodeFileByTask(
 2886                jobId,
 2887                taskId,
 2888                filePath,
 2889                stream,
 2890                byteRange,
 2891                bhMgr,
 2892                cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
 0893        }
 894
 895        /// <summary>
 896        /// Copies the contents of a file from the specified task's directory on its compute node to the given <see cref
 897        /// </summary>
 898        /// <param name="jobId">The id of the job containing the task.</param>
 899        /// <param name="taskId">The id of the task.</param>
 900        /// <param name="filePath">The path of the file to retrieve.</param>
 901        /// <param name="stream">The stream to copy the file contents to.</param>
 902        /// <param name="byteRange">A byte range defining what section of the file to copy. If omitted, the entire file 
 903        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 904        /// <param name="cancellationToken">A <see cref="CancellationToken"/> for controlling the lifetime of the asynch
 905        /// <remarks>The get file operation runs asynchronously.</remarks>
 906        public Task CopyNodeFileContentToStreamAsync(
 907            string jobId,
 908            string taskId,
 909            string filePath,
 910            Stream stream,
 911            GetFileRequestByteRange byteRange = null,
 912            IEnumerable<BatchClientBehavior> additionalBehaviors = null,
 913            CancellationToken cancellationToken = default(CancellationToken))
 914        {
 915            // set up behavior manager
 1916            BehaviorManager bhMgr = new BehaviorManager(this.CustomBehaviors, additionalBehaviors);
 1917            return this.CopyNodeFileContentToStreamAsyncImpl(jobId, taskId, filePath, stream, byteRange, bhMgr, cancella
 918        }
 919
 920        /// <summary>
 921        /// Copies the contents of a file from the specified task's directory on its compute node to the given <see cref
 922        /// </summary>
 923        /// <param name="jobId">The id of the job containing the task.</param>
 924        /// <param name="taskId">The id of the task.</param>
 925        /// <param name="filePath">The path of the file to retrieve.</param>
 926        /// <param name="stream">The stream to copy the file contents to.</param>
 927        /// <param name="byteRange">A byte range defining what section of the file to copy. If omitted, the entire file 
 928        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 929        /// <remarks>This is a blocking operation.  For a non-blocking equivalent, see <see cref="CopyNodeFileContentToS
 930        public void CopyNodeFileContentToStream(
 931            string jobId,
 932            string taskId,
 933            string filePath,
 934            Stream stream,
 935            GetFileRequestByteRange byteRange = null,
 936            IEnumerable<BatchClientBehavior> additionalBehaviors = null)
 937        {
 0938            Task asyncTask = this.CopyNodeFileContentToStreamAsync(jobId, taskId, filePath, stream, byteRange, additiona
 0939            asyncTask.WaitAndUnaggregateException(this.CustomBehaviors, additionalBehaviors);
 0940        }
 941
 942        internal Task<string> CopyNodeFileContentToStringAsyncImpl(
 943            string jobId,
 944            string taskId,
 945            string filePath,
 946            Encoding encoding,
 947            GetFileRequestByteRange byteRange,
 948            BehaviorManager bhMgr,
 949            CancellationToken cancellationToken)
 950        {
 1951            return UtilitiesInternal.ReadNodeFileAsStringAsync(
 1952                // Note that behaviors is purposefully dropped in the below call since it's already managed by the bhMgr
 2953                (stream, bRange, behaviors, ct) => this.CopyNodeFileContentToStreamAsyncImpl(jobId, taskId, filePath, st
 1954                encoding,
 1955                byteRange,
 1956                additionalBehaviors: null,
 1957                cancellationToken: cancellationToken);
 958        }
 959
 960        /// <summary>
 961        /// Reads the contents of a file from the specified task's directory on its compute node into a string.
 962        /// </summary>
 963        /// <param name="jobId">The id of the job containing the task.</param>
 964        /// <param name="taskId">The id of the task.</param>
 965        /// <param name="filePath">The path of the file to retrieve.</param>
 966        /// <param name="encoding">The encoding to use. If no value or null is specified, UTF8 is used.</param>
 967        /// <param name="byteRange">A byte range defining what section of the file to copy. If omitted, the entire file 
 968        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 969        /// <param name="cancellationToken">A <see cref="CancellationToken"/> for controlling the lifetime of the asynch
 970        /// <returns>The contents of the file, as a string</returns>
 971        public Task<string> CopyNodeFileContentToStringAsync(
 972            string jobId,
 973            string taskId,
 974            string filePath,
 975            Encoding encoding = null,
 976            GetFileRequestByteRange byteRange = null,
 977            IEnumerable<BatchClientBehavior> additionalBehaviors = null,
 978            CancellationToken cancellationToken = default(CancellationToken))
 979        {
 980            // set up behavior manager
 1981            BehaviorManager bhMgr = new BehaviorManager(this.CustomBehaviors, additionalBehaviors);
 1982            return CopyNodeFileContentToStringAsyncImpl(jobId, taskId, filePath, encoding, byteRange, bhMgr, cancellatio
 983        }
 984
 985        /// <summary>
 986        /// Reads the contents of a file from the specified task's directory on its compute node into a string.
 987        /// </summary>
 988        /// <param name="jobId">The id of the job containing the task.</param>
 989        /// <param name="taskId">The id of the task.</param>
 990        /// <param name="filePath">The path of the file to retrieve.</param>
 991        /// <param name="encoding">The encoding to use. If no value or null is specified, UTF8 is used.</param>
 992        /// <param name="byteRange">A byte range defining what section of the file to copy. If omitted, the entire file 
 993        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 994        /// <returns>The contents of the file, as a string</returns>
 995        public string CopyNodeFileContentToString(
 996            string jobId,
 997            string taskId,
 998            string filePath,
 999            Encoding encoding = null,
 1000            GetFileRequestByteRange byteRange = null,
 1001            IEnumerable<BatchClientBehavior> additionalBehaviors = null)
 1002        {
 01003            Task<string> asyncTask = this.CopyNodeFileContentToStringAsync(jobId, taskId, filePath, encoding, byteRange,
 01004            return asyncTask.WaitAndUnaggregateException(this.CustomBehaviors, additionalBehaviors);
 1005        }
 1006
 1007        /// <summary>
 1008        /// Deletes the specified file from the task's directory on its compute node.
 1009        /// </summary>
 1010        /// <param name="jobId">The id of the job containing the task.</param>
 1011        /// <param name="taskId">The id of the task.</param>
 1012        /// <param name="filePath">The path of the file to delete.</param>
 1013        /// <param name="recursive">
 1014        /// If the file-path parameter represents a directory instead of a file, you can set the optional
 1015        /// recursive parameter to true to delete the directory and all of the files and subdirectories in it. If recurs
 1016        /// then the directory must be empty or deletion will fail.
 1017        /// </param>
 1018        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 1019        /// <param name="cancellationToken">A <see cref="CancellationToken"/> for controlling the lifetime of the asynch
 1020        /// <returns>A <see cref="System.Threading.Tasks.Task"/> that represents the asynchronous operation.</returns>
 1021        /// <remarks>The delete operation runs asynchronously.</remarks>
 1022        public async System.Threading.Tasks.Task DeleteNodeFileAsync(
 1023            string jobId,
 1024            string taskId,
 1025            string filePath,
 1026            bool? recursive = null,
 1027            IEnumerable<BatchClientBehavior> additionalBehaviors = null,
 1028            CancellationToken cancellationToken = default(CancellationToken))
 1029        {
 1030            // craft the behavior manager for this call
 11031            BehaviorManager bhMgr = new BehaviorManager(this.CustomBehaviors, additionalBehaviors);
 1032
 11033            var asyncTask = this.ParentBatchClient.ProtocolLayer.DeleteNodeFileByTask(
 11034                jobId,
 11035                taskId,
 11036                filePath,
 11037                recursive,
 11038                bhMgr,
 11039                cancellationToken);
 1040
 11041            await asyncTask.ConfigureAwait(continueOnCapturedContext: false);
 01042        }
 1043
 1044        /// <summary>
 1045        /// Deletes the specified file from the task's directory on its compute node.
 1046        /// </summary>
 1047        /// <param name="jobId">The id of the job containing the task.</param>
 1048        /// <param name="taskId">The id of the task.</param>
 1049        /// <param name="filePath">The path of the file to delete.</param>
 1050        /// <param name="recursive">
 1051        /// If the file-path parameter represents a directory instead of a file, you can set the optional
 1052        /// recursive parameter to true to delete the directory and all of the files and subdirectories in it. If recurs
 1053        /// then the directory must be empty or deletion will fail.
 1054        /// </param>
 1055        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 1056        /// <returns>A <see cref="System.Threading.Tasks.Task"/> that represents the asynchronous operation.</returns>
 1057        /// <remarks>This is a blocking operation.  For a non-blocking equivalent, see <see cref="DeleteNodeFileAsync"/>
 1058        public void DeleteNodeFile(
 1059            string jobId,
 1060            string taskId,
 1061            string filePath,
 1062            bool? recursive = null,
 1063            IEnumerable<BatchClientBehavior> additionalBehaviors = null)
 1064        {
 01065            Task asyncTask = this.DeleteNodeFileAsync(jobId, taskId, filePath, recursive, additionalBehaviors);
 01066            asyncTask.WaitAndUnaggregateException(this.CustomBehaviors, additionalBehaviors);
 01067        }
 1068
 1069        internal Task AddTaskAsyncImpl(
 1070            string jobId,
 1071            IEnumerable<CloudTask> tasksToAdd,
 1072            BatchClientParallelOptions parallelOptions,
 1073            ConcurrentBag<ConcurrentDictionary<Type, IFileStagingArtifact>> fileStagingArtifacts,
 1074            TimeSpan? timeout,
 1075            BehaviorManager behaviorManager)
 1076        {
 71077            AddTasksWorkflowManager addTasksWorkflowManager = new AddTasksWorkflowManager(
 71078                this,
 71079                jobId,
 71080                parallelOptions,
 71081                fileStagingArtifacts,
 71082                behaviorManager);
 1083
 61084            return addTasksWorkflowManager.AddTasksAsync(tasksToAdd, timeout);
 1085        }
 1086
 1087        /// <summary>
 1088        /// Adds tasks to a job.
 1089        /// </summary>
 1090        /// <param name="jobId">The id of the job to which to add the tasks.</param>
 1091        /// <param name="tasksToAdd">The <see cref="CloudTask"/>s to add.</param>
 1092        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 1093        /// <param name="parallelOptions">
 1094        /// Controls the number of simultaneous parallel AddTaskCollection requests issued to the Batch service.  Each A
 1095        /// <see cref="Constants.MaxTasksInSingleAddTaskCollectionRequest"/> tasks in it.
 1096        /// Also controls the cancellation token for the operation.
 1097        /// If omitted, the default is used (see <see cref="BatchClientParallelOptions"/>.)
 1098        /// </param>
 1099        /// <param name="fileStagingArtifacts">An optional collection to receive information about the file staging proc
 1100        /// An entry is added to the <see cref="ConcurrentBag{T}"/> for each set of tasks grouped for submission to the 
 1101        /// Unlike single-task adds, you cannot use this parameter to customize the file staging process.
 1102        /// For more information about the format of each entry, see <see cref="IFileStagingArtifact"/>.</param>
 1103        /// <param name="timeout">The amount of time after which the operation times out.</param>
 1104        /// <returns>A <see cref="System.Threading.Tasks.Task"/> object that represents the asynchronous operation.</ret
 1105        /// <remarks>
 1106        /// <para>The add task operation runs asynchronously.</para>
 1107        /// <para>This method is not atomic; that is, it is possible for the method to start adding tasks and
 1108        /// then fail. The collection of tasks to add is broken down into chunks of size at most <see cref="Constants.Ma
 1109        /// and an AddTaskCollection request is issued for each chunk.  Requests may be issued in parallel according to
 1110        /// the <paramref name="parallelOptions"/>.</para>
 1111        /// <para>Issuing a large number of simultaneous requests to the Batch service can incur HTTP connection restric
 1112        /// If you are performing many of these operations in parallel (or have specified a large MaxDegreeOfParallelism
 1113        /// the parallelOptions) and are seeing client side timeouts, please see
 1114        /// http://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.defaultconnectionlimit%28v=vs.110%29.
 1115        /// <para>The progress of the operation in the face of errors is determined by <see cref="AddTaskCollectionResul
 1116        /// You do not normally need to specify this behavior, as the Batch client uses a default which works in normal 
 1117        /// If you do want to customize this behavior, specify an AddTaskCollectionResultHandler in the <see cref="Custo
 1118        /// or <paramref name="additionalBehaviors"/> collections.</para>
 1119        /// </remarks>
 1120        /// <exception cref="ParallelOperationsException">Thrown if one or more requests to the Batch service fail.</exc
 1121        public async System.Threading.Tasks.Task AddTaskAsync(
 1122            string jobId,
 1123            IEnumerable<CloudTask> tasksToAdd,
 1124            BatchClientParallelOptions parallelOptions = null,
 1125            ConcurrentBag<ConcurrentDictionary<Type, IFileStagingArtifact>> fileStagingArtifacts = null,
 1126            TimeSpan? timeout = null,
 1127            IEnumerable<BatchClientBehavior> additionalBehaviors = null)
 1128        {
 1129            // craft the behavior manager for this call
 71130            BehaviorManager bhMgr = new BehaviorManager(this.CustomBehaviors, additionalBehaviors);
 1131
 71132            await this.AddTaskAsyncImpl(
 71133                jobId,
 71134                tasksToAdd,
 71135                parallelOptions,
 71136                fileStagingArtifacts,
 71137                timeout,
 71138                bhMgr).ConfigureAwait(continueOnCapturedContext: false);
 01139        }
 1140
 1141        /// <summary>
 1142        /// Adds tasks to a job.
 1143        /// </summary>
 1144        /// <param name="jobId">The id of the job to which to add the tasks.</param>
 1145        /// <param name="tasksToAdd">The <see cref="CloudTask"/>s to add.</param>
 1146        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 1147        /// <param name="parallelOptions">
 1148        /// Controls the number of simultaneous parallel AddTaskCollection requests issued to the Batch service.  Each A
 1149        /// <see cref="Constants.MaxTasksInSingleAddTaskCollectionRequest"/> tasks in it.
 1150        /// Also controls the cancellation token for the operation.
 1151        /// If omitted, the default is used (see <see cref="BatchClientParallelOptions"/>.)
 1152        /// </param>
 1153        /// <param name="fileStagingArtifacts">An optional collection to receive information about the file staging proc
 1154        /// An entry is added to the <see cref="ConcurrentBag{T}"/> for each set of tasks grouped for submission to the 
 1155        /// Unlike single-task adds, you cannot use this parameter to customize the file staging process.
 1156        /// For more information about the format of each entry, see <see cref="IFileStagingArtifact"/>.</param>
 1157        /// <param name="timeout">The amount of time after which the operation times out.</param>
 1158        /// <remarks>
 1159        /// <para>This is a blocking operation; for a non-blocking equivalent, see <see cref="AddTaskAsync(string, IEnum
 1160        /// <para>This method is not atomic; that is, it is possible for the method to start adding tasks and
 1161        /// then fail. The collection of tasks to add is broken down into chunks of size at most <see cref="Constants.Ma
 1162        /// and an AddTaskCollection request is issued for each chunk.  Requests may be issued in parallel according to
 1163        /// the <paramref name="parallelOptions"/>.</para>
 1164        /// <para>Issuing a large number of simultaneous requests to the Batch service can incur HTTP connection restric
 1165        /// If you are performing many of these operations in parallel (or have specified a large MaxDegreeOfParallelism
 1166        /// the parallelOptions) and are seeing client side timeouts, please see
 1167        /// http://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.defaultconnectionlimit%28v=vs.110%29.
 1168        /// <para>The progress of the operation in the face of errors is determined by <see cref="AddTaskCollectionResul
 1169        /// You do not normally need to specify this behavior, as the Batch client uses a default which works in normal 
 1170        /// If you do want to customize this behavior, specify an AddTaskCollectionResultHandler in the <see cref="Custo
 1171        /// or <paramref name="additionalBehaviors"/> collections.</para>
 1172        /// </remarks>
 1173        /// <exception cref="ParallelOperationsException">Thrown if one or more requests to the Batch service fail.</exc
 1174        public void AddTask(
 1175            string jobId,
 1176            IEnumerable<CloudTask> tasksToAdd,
 1177            BatchClientParallelOptions parallelOptions = null,
 1178            ConcurrentBag<ConcurrentDictionary<Type, IFileStagingArtifact>> fileStagingArtifacts = null,
 1179            TimeSpan? timeout = null,
 1180            IEnumerable<BatchClientBehavior> additionalBehaviors = null)
 1181        {
 01182            Task asyncTask = this.AddTaskAsync(
 01183                jobId,
 01184                tasksToAdd,
 01185                parallelOptions,
 01186                fileStagingArtifacts,
 01187                timeout,
 01188                additionalBehaviors);
 1189
 01190            asyncTask.WaitAndUnaggregateException(this.CustomBehaviors, additionalBehaviors);
 01191        }
 1192
 1193        /// <summary>
 1194        /// Gets lifetime summary statistics for all of the jobs in the current account.
 1195        /// Statistics are aggregated across all jobs that have ever existed in the account, from account creation to th
 1196        /// Batch service performs periodic roll-up of statistics. The typical delay is about 30 minutes.
 1197        /// </summary>
 1198        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 1199        /// <param name="cancellationToken">A <see cref="CancellationToken"/> for controlling the lifetime of the asynch
 1200        /// <returns>The aggregated job statistics.</returns>
 1201        /// <remarks>The get statistics operation runs asynchronously.</remarks>
 1202        public async System.Threading.Tasks.Task<JobStatistics> GetAllLifetimeStatisticsAsync(
 1203            IEnumerable<BatchClientBehavior> additionalBehaviors = null,
 1204            CancellationToken cancellationToken = default(CancellationToken))
 1205        {
 1206            // craft the behavior manager for this call
 11207            BehaviorManager bhMgr = new BehaviorManager(this.CustomBehaviors, additionalBehaviors);
 1208
 11209            System.Threading.Tasks.Task<AzureOperationResponse<Models.JobStatistics, Models.JobGetAllLifetimeStatisticsH
 11210                this.ParentBatchClient.ProtocolLayer.GetAllJobLifetimeStats(
 11211                    bhMgr,
 11212                    cancellationToken);
 1213
 11214            var response = await asyncTask.ConfigureAwait(continueOnCapturedContext: false);
 1215
 01216            JobStatistics statistics = new JobStatistics(response.Body);
 1217
 01218            return statistics;
 01219        }
 1220
 1221        /// <summary>
 1222        /// Gets lifetime summary statistics for all of the jobs in the current account.
 1223        /// Statistics are aggregated across all jobs that have ever existed in the account, from account creation to th
 1224        /// Batch service performs periodic roll-up of statistics. The typical delay is about 30 minutes.
 1225        /// </summary>
 1226        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 1227        /// <returns>The aggregated job statistics.</returns>
 1228        /// <remarks>This is a blocking operation; for a non-blocking equivalent, see <see cref="GetAllLifetimeStatistic
 1229        public JobStatistics GetAllLifetimeStatistics(IEnumerable<BatchClientBehavior> additionalBehaviors = null)
 1230        {
 01231            Task<JobStatistics> asyncTask = this.GetAllLifetimeStatisticsAsync(additionalBehaviors);
 01232            JobStatistics statistics = asyncTask.WaitAndUnaggregateException(this.CustomBehaviors, additionalBehaviors);
 1233
 01234            return statistics;
 1235        }
 1236
 1237        /// <summary>
 1238        /// Enumerates the status of <see cref="CloudJob.JobPreparationTask"/> and <see cref="CloudJob.JobReleaseTask"/>
 1239        /// </summary>
 1240        /// <param name="jobId">The id of the job.</param>
 1241        /// <param name="detailLevel">A <see cref="DetailLevel"/> used for filtering the list and for controlling which 
 1242        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 1243        /// <returns>An <see cref="IPagedEnumerable{JobPreparationAndReleaseTaskExecutionInformation}"/> that can be use
 1244        /// <remarks>This method returns immediately; the statuses are retrieved from the Batch service only when the co
 1245        /// Retrieval is non-atomic; statuses are retrieved in pages during enumeration of the collection.</remarks>
 1246        public IPagedEnumerable<JobPreparationAndReleaseTaskExecutionInformation> ListJobPreparationAndReleaseTaskStatus
 1247        {
 1248            // craft the behavior manager for this call
 21249            BehaviorManager bhMgr = new BehaviorManager(this.CustomBehaviors, additionalBehaviors);
 1250
 21251            PagedEnumerable<JobPreparationAndReleaseTaskExecutionInformation> enumerable = new PagedEnumerable<JobPrepar
 21252                () =>
 21253                {
 21254                    // here is the actual strongly typed enumerator
 41255                    AsyncListJobPrepReleaseTaskStatusEnumerator typedEnumerator = new AsyncListJobPrepReleaseTaskStatusE
 21256
 21257                    // here is the base
 21258                    PagedEnumeratorBase<JobPreparationAndReleaseTaskExecutionInformation> enumeratorBase = typedEnumerat
 21259
 41260                    return enumeratorBase;
 21261                });
 1262
 21263            return enumerable;
 1264        }
 1265
 1266#endregion // JobOperations
 1267
 1268#region // internal/private
 1269
 11681270        internal BatchClient ParentBatchClient { get; set;}
 1271
 1272#endregion // internal/private
 1273    }
 1274}