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); }