title: Uploading files to Azure blob storage taking more time for larger files
body: <blockquote>
    <p>Hi All...</p>
    
    <p>I am trying to uploading the lager file (size more than 100 MB) files
    to Azure blob storage.Below is the code.</p>
    
    <p>My problem is even though I have used BeginPutBlock with TPL (Task
    Parallelism) it is taking more time (20 Min for 100 MB uploading). But
    i have to upload the files more than 2 GB size. Can anyone please help
    me on this.</p>
  </blockquote>
  
  <pre><code>namespace BlobSamples {
      public class UploadAsync
      {
          static void Main(string[] args)
          {
              //string filePath = @"D:\Frameworks\DNCMag-Issue26-DoubleSpread.pdf";
              string filePath = @"E:\E Books\NageswaraRao Meterial\ebooks\applied_asp.net_4_in_context.pdf";
              string accountName = "{account name}";
              string accountKey = "{account key}";
              string containerName = "sampleContainer";
              string blobName = Path.GetFileName(filePath);
              //byte[] fileContent = File.ReadAllBytes(filePath);
              Stream fileContent = System.IO.File.OpenRead(filePath);
  
              StorageCredentials creds = new StorageCredentials(accountName, accountKey);
              CloudStorageAccount storageAccount = new CloudStorageAccount(creds, useHttps: true);
              CloudBlobClient blobclient = storageAccount.CreateCloudBlobClient();
              CloudBlobContainer container = blobclient.GetContainerReference(containerName);
              CloudBlockBlob blob = container.GetBlockBlobReference(blobName);
  
              // Define your retry strategy: retry 5 times, starting 1 second apart
              // and adding 2 seconds to the interval each retry.
              var retryStrategy = new Incremental(5, TimeSpan.FromSeconds(1),
                TimeSpan.FromSeconds(2));
  
              // Define your retry policy using the retry strategy and the Azure storage
              // transient fault detection strategy.
              var retryPolicy =
                new RetryPolicy&lt;StorageTransientErrorDetectionStrategy&gt;(retryStrategy);
  
              // Receive notifications about retries.
              retryPolicy.Retrying += (sender, arg) =&gt;
                  {
                      // Log details of the retry.
                      var msg = String.Format("Retry - Count:{0}, Delay:{1}, Exception:{2}",
                          arg.CurrentRetryCount, arg.Delay, arg.LastException);
                  };
  
              Console.WriteLine("Upload Started" + DateTime.Now);
              ChunkedUploadStreamAsync(blob, fileContent, (1024*1024), retryPolicy);
              Console.WriteLine("Upload Ended" + DateTime.Now);
              Console.ReadLine();
          }
  
          private static Task PutBlockAsync(CloudBlockBlob blob, string id, Stream stream, RetryPolicy policy)
          {
              Func&lt;Task&gt; uploadTaskFunc = () =&gt; Task.Factory
                  .FromAsync(
                      (asyncCallback, state) =&gt; blob.BeginPutBlock(id, stream, null, null, null, null, asyncCallback, state)
                      , blob.EndPutBlock
                      , null
                  );
              Console.WriteLine("Uploaded " + id + DateTime.Now);
              return policy.ExecuteAsync(uploadTaskFunc);
          }
  
          public static Task ChunkedUploadStreamAsync(CloudBlockBlob blob, Stream source, int chunkSize, RetryPolicy policy)
          {
              var blockids = new List&lt;string&gt;();
              var blockid = 0;
  
              int count;
  
              // first create a list of TPL Tasks for uploading blocks asynchronously
              var tasks = new List&lt;Task&gt;();
  
              var bytes = new byte[chunkSize];
              while ((count = source.Read(bytes, 0, bytes.Length)) != 0)
              {
                  var id = Convert.ToBase64String(BitConverter.GetBytes(++blockid));
                  blockids.Add(id);
                  tasks.Add(PutBlockAsync(blob, id, new MemoryStream(bytes, true), policy));
                  bytes = new byte[chunkSize]; //need a new buffer to avoid overriding previous one
              }
  
              return Task.Factory.ContinueWhenAll(
                  tasks.ToArray(),
                  array =&gt;
                  {
                      // propagate exceptions and make all faulted Tasks as observed
                      Task.WaitAll(array);
                      policy.ExecuteAction(() =&gt; blob.PutBlockListAsync(blockids));
                      Console.WriteLine("Uploaded Completed " + DateTime.Now);
                  });
          }
      } }
  </code></pre>