Saturday, September 12, 2015

Async Blob Upload with Progress

 

Sorry for the bad formatting…

---

public async Task UpbloadBlobAsync(string blobContainer, string path, string name, bool zip, CancellationToken cancellationToken, IProgress<BlobTransferProgress> progress)
     {
         CloudBlobContainer cloudBlobContainer = GetBlobContainer(blobContainer);

         CloudBlockBlob cloudBlockBlob = cloudBlobContainer.GetBlockBlobReference(name);

         //TODO: zip           

         try
         {
             FileInfo fileInfo = new FileInfo(path);
             long fileSize = fileInfo.Length;
             long fileSizeForReporting = fileSize;

             if (fileSize < Constants.DEFAULT_BUFFER_SIZE)
             {
                 using (FileStream fileStream = File.Open(path, FileMode.Open))
                 {
                     await cloudBlockBlob.UploadFromStreamAsync(fileStream, cancellationToken);
                 }

                 return;
             }

             int index = 1;
             long startPosition = 0;
             long bytesUploaded = 0;

             do
             {
                 long bufferSize = Math.Min(Constants.DEFAULT_BUFFER_SIZE, fileSize);

                 byte[] buffer = new byte[bufferSize];

                 using (FileStream fileStream = new FileStream(path, FileMode.Open))
                 {
                     fileStream.Position = startPosition;
                     fileStream.Read(buffer, 0, (int)bufferSize);
                 }

                 string blockId = Convert.ToBase64String(Encoding.UTF8.GetBytes(index.ToString("d6")));

                 if (cancellationToken.IsCancellationRequested)
                 {
                     cloudBlockBlob.Delete();
                     return;
                 }

                 using (MemoryStream memoryStream = new MemoryStream(buffer))
                 {
                     using (Task putBlockTask = cloudBlockBlob.PutBlockAsync(blockId, memoryStream, null, cancellationToken))
                     {
                         await putBlockTask.ContinueWith(t =>
                         {
                             bytesUploaded += bufferSize;
                             fileSize -= bufferSize;
                             startPosition += bufferSize;
                             index++;

                             double percentComplete = 100 * bytesUploaded / fileSizeForReporting;

                             progress.Report(new BlobTransferProgress(fileSize, bytesUploaded, percentComplete));
                         },
                             cancellationToken);
                     }
                 }
             } while (fileSize > 0);
         }
         catch (Exception exception)
         {
             progress.Report(new BlobTransferProgress(exception.Message));
         }
     }

And in my unit test, you can see the progress (plus the task wait where “I am doing other stuff”):

 

Remaining Bytes = 9737856 - Bytes uploaded = 262144 - Percent Complete = 2

Remaining Bytes = 9475712 - Bytes uploaded = 524288 - Percent Complete = 5

Remaining Bytes = 9213568 - Bytes uploaded = 786432 - Percent Complete = 7

Remaining Bytes = 8951424 - Bytes uploaded = 1048576 - Percent Complete = 10

Remaining Bytes = 8689280 - Bytes uploaded = 1310720 - Percent Complete = 13

Remaining Bytes = 8427136 - Bytes uploaded = 1572864 - Percent Complete = 15

Remaining Bytes = 8164992 - Bytes uploaded = 1835008 - Percent Complete = 18

Remaining Bytes = 7902848 - Bytes uploaded = 2097152 - Percent Complete = 20

Remaining Bytes = 7640704 - Bytes uploaded = 2359296 - Percent Complete = 23

Remaining Bytes = 7378560 - Bytes uploaded = 2621440 - Percent Complete = 26

Doing other stuff...
Remaining Bytes = 7116416 - Bytes uploaded = 2883584 - Percent Complete = 28

Remaining Bytes = 6854272 - Bytes uploaded = 3145728 - Percent Complete = 31

Remaining Bytes = 6592128 - Bytes uploaded = 3407872 - Percent Complete = 34

Remaining Bytes = 6329984 - Bytes uploaded = 3670016 - Percent Complete = 36

Remaining Bytes = 6067840 - Bytes uploaded = 3932160 - Percent Complete = 39

Remaining Bytes = 5805696 - Bytes uploaded = 4194304 - Percent Complete = 41

Remaining Bytes = 5543552 - Bytes uploaded = 4456448 - Percent Complete = 44

Remaining Bytes = 5281408 - Bytes uploaded = 4718592 - Percent Complete = 47

Remaining Bytes = 5019264 - Bytes uploaded = 4980736 - Percent Complete = 49

Remaining Bytes = 4757120 - Bytes uploaded = 5242880 - Percent Complete = 52

Remaining Bytes = 4494976 - Bytes uploaded = 5505024 - Percent Complete = 55

Doing other stuff...
Remaining Bytes = 4232832 - Bytes uploaded = 5767168 - Percent Complete = 57

Remaining Bytes = 3970688 - Bytes uploaded = 6029312 - Percent Complete = 60

Remaining Bytes = 3708544 - Bytes uploaded = 6291456 - Percent Complete = 62

Remaining Bytes = 3446400 - Bytes uploaded = 6553600 - Percent Complete = 65

Remaining Bytes = 3184256 - Bytes uploaded = 6815744 - Percent Complete = 68

Remaining Bytes = 2922112 - Bytes uploaded = 7077888 - Percent Complete = 70

Remaining Bytes = 2659968 - Bytes uploaded = 7340032 - Percent Complete = 73

Remaining Bytes = 2397824 - Bytes uploaded = 7602176 - Percent Complete = 76

Remaining Bytes = 2135680 - Bytes uploaded = 7864320 - Percent Complete = 78

Remaining Bytes = 1873536 - Bytes uploaded = 8126464 - Percent Complete = 81

Remaining Bytes = 1611392 - Bytes uploaded = 8388608 - Percent Complete = 83

Remaining Bytes = 1349248 - Bytes uploaded = 8650752 - Percent Complete = 86

Remaining Bytes = 1087104 - Bytes uploaded = 8912896 - Percent Complete = 89

Remaining Bytes = 824960 - Bytes uploaded = 9175040 - Percent Complete = 91

Remaining Bytes = 562816 - Bytes uploaded = 9437184 - Percent Complete = 94

Remaining Bytes = 300672 - Bytes uploaded = 9699328 - Percent Complete = 96

Remaining Bytes = 38528 - Bytes uploaded = 9961472 - Percent Complete = 99

Remaining Bytes = 0 - Bytes uploaded = 10000000 - Percent Complete = 100

RanToCompletion

No comments:

Disclaimer

Content on this site is provided "AS IS" with no warranties and confers no rights. Additionally, all content on this site is my own personal opinion and does not represent my employer's view in any way.