HttpClient.GetAsync()& CloudBlobBlock.UploadFromStreamAsync() - 这是如何执行的?

时间:2016-03-10 13:24:16

标签: .net async-await azure-storage-blobs dotnet-httpclient

我需要从一个地方下载文件,然后将其上传到azure blob。我还需要在完成时返回blob的大小:

public async Task<Stream> Download(string url)
{
   using (var client = new HttpClient())
   {
        return await client.GetStreamAsync(url);
   }
}

public async Task<long> Upload(Stream stream, string filename) 
{
   var container = GetBlobContainer(..);
   var blob = container.GetBlockBlobReference(filename);

   await blob.UploadFromStreamAsync(stream);
   blob.FetchAttributes();

   return blob.Properties.Length;
}

public async Task<long> Action()
{
   var stream = await Download("https://.....");
   var size = await Upload(stream, "newfile.dat");

   return size;
}

问题

  • 在将完整的流下载到内存之前是否会调用Upload方法?

  • Upload开始接收字节后,HttpClient是否会开始将字节上传到azure?

  • 如果没有 - 是否可以这样做?

加分:

  • 将生成多少个不同的上下文? .ConfigureAwait(false)是否应该用于限制上下文切换?

  • blob.FetchAttributes()是获得blob大小的正确方法吗?

1 个答案:

答案 0 :(得分:2)

  

在将完整的流下载到内存之前是否会调用Upload方法?

不,所以默认情况下,HttpClient会将整个响应下载到内存中,然后会为您提供流。见:HttpClient.SendAsync。您使用的超载指定HttpCompletionOption.ResponseContentRead。但更糟糕的是,您的代码无法正常工作,您在使用流之前会处置HttpClient,这会导致流关闭。

  

一旦HttpClient开始接收字节,上传是否会开始将字节上传到azure?

再次,不,请参阅之前的回答。

  

如果没有 - 是否可以这样做?

是的,请使用我之前列出的SendAsync重载并设置相应的HttpCompletionOption哦,并修复我提到的处理问题。 :)

  

将生成多少个不同的上下文?应该.ConfigureAwait(false)用于限制上下文切换吗?

不确定你的意思&#34; conetxts&#34;,我假设执行上下文?没有看到更多代码就很难说。但我会建议使用.ConfigureAwait(false),除非涉及到一些用户界面。

  

blob.FetchAttributes()是获取blob大小的正确方法吗?

就个人而言,我会自己使用来自客户端响应标头的内容长度。但基于MSDN文档,这看起来是正确的。