public async Task ParallelDownloadSlowTest()
        {
            string             inputFileName  = Path.GetTempFileName();
            string             outputFileName = Path.GetTempFileName();
            CloudBlobContainer container      = GetRandomContainerReference();

            try
            {
                await container.CreateAsync();

                CloudBlockBlob blob = container.GetBlockBlobReference("largeblob1");

                long bufferSize = 12 * Constants.KB;
                long offSet     = 0;
                using (FileStream file = new FileStream(inputFileName, FileMode.Create, FileAccess.Write))
                {
                    while (offSet < 12 * Constants.MB)
                    {
                        byte[] buffer = GetRandomBuffer(bufferSize);
                        await file.WriteAsync(buffer, 0, buffer.Length);

                        offSet += bufferSize;
                    }
                }

                BlobRequestOptions options = new BlobRequestOptions();
                options.ParallelOperationThreadCount = 16;
                await blob.UploadFromFileAsync(inputFileName, null, options, null);

                int  parallelIOCount  = 2;
                long rangeSizeInBytes = 4 * Constants.MB;
                CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();

                DelayingDownloadRangeCloudBlob wrapperBlob = new DelayingDownloadRangeCloudBlob(blob.SnapshotQualifiedUri, blob.ServiceClient, 1000, 1000000);
                await ParallelDownloadToFile.Start(wrapperBlob, outputFileName,
                                                   FileMode.Create,
                                                   parallelIOCount,
                                                   rangeSizeInBytes,
                                                   0,
                                                   null,
                                                   10000 /* Amount of time to wait before abort / retry */,
                                                   null,
                                                   null,
                                                   null,
                                                   CancellationToken.None).Task;

                await blob.DeleteAsync();

                Assert.IsTrue(FilesAreEqual(inputFileName, outputFileName));
            }
            finally
            {
                container.DeleteIfExists();
                File.Delete(inputFileName);
                File.Delete(outputFileName);
            }
        }
        /// <summary>
        /// Starts the download of a blob to a file.
        /// </summary>
        /// <param name="blob">The <see cref="CloudBlob"/> to download.</param>
        /// <param name="filePath">A string containing the path to the target file.</param>
        /// <param name="fileMode">A <see cref="System.IO.FileMode"/> enumeration value that determines how to open or create the file.</param>
        /// <param name="parallelIOCount">The maximum number of ranges that can be downloaded concurrently</param>
        /// <param name="rangeSizeInBytes">The size of each individual range in bytes that is being dowloaded in parallel.
        /// The range size must be a multiple of 4 KB and a minimum of 4 MB with a default value of 16 MB.</param>
        /// <param name="offset">The offset of the blob.</param>
        /// <param name="length">The number of bytes to download.</param>
        /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the condition that must be met in order for the request to proceed.</param>
        /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies additional options for the request.</param>
        /// <param name="operationContext">An <see cref="OperationContext"/> object that represents the context for the current operation.</param>
        /// <param name="cancellationToken">A <see cref="CancellationToken"/> to observe while waiting for a task to complete.</param>
        /// <returns>A <see cref="ParallelDownloadToFile"/> object which contains a task that can be awaited for completion.</returns>
        public static ParallelDownloadToFile Start(CloudBlob blob, string filePath, FileMode fileMode, int parallelIOCount, long?rangeSizeInBytes, long offset, long?length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken)
        {
            ParallelDownloadToFile parallelDownload = new ParallelDownloadToFile(blob, filePath, offset, length, cancellationToken);

            parallelDownload.operationContext   = operationContext;
            parallelDownload.blobRequestOptions = options;
            parallelDownload.accessCondition    = accessCondition;

            parallelDownload.Task = parallelDownload.StartAsync(fileMode, parallelIOCount, rangeSizeInBytes);

            return(parallelDownload);
        }