使用.NET 4.5的异步async和await向客户端异步传输Azure blob流。

10

我正在使用HttpTaskAsyncHandler实现自己的异步HTTP处理程序,并使用async & await使其完全异步化。

我想直接将Azure Blob流式传输到客户端。虽然我可以将客户端重定向到Blob URL并让他们直接下载,但假设我不想这样做(例如我的Blob是私有的)。

这是我目前的实现:

代码:

    public async Task<bool> DownloadToStreamAsync(ICloudBlob blob, Stream stream)
    {
        bool blobFound = true; 
        IAsyncResult asyncResult = blob.BeginDownloadToStream(stream, null, null);
        await Task.Factory.FromAsync(asyncResult, (r) =>
        {
            try
            {
                blob.EndDownloadToStream(r);
            }
            catch (StorageException)
            {
                blobFound = false;
            }
        });
        return blobFound;
    }

使用方法:

    public override async Task ProcessRequestAsync(HttpContext context)
    {
        CloudStorageAccount storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageAccountConnectionString"));
        CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
        CloudBlobContainer container = blobClient.GetContainerReference("container1");
        CloudBlockBlob blockBlob = container.GetBlockBlobReference("blob1.txt");

        await DownloadToStreamAsync(blockBlob, context.Response.OutputStream);
    }

这段代码是否完全异步,会释放我的HTTP服务器以处理其他客户端,同时进行流式传输?(如果我只有一个服务器线程)

是否可能保持blob压缩(GZIP)并使用Content-Encoding:gzip让客户端进行解压缩?

更新:(截至Storage 2.1.0.0 RC)

现在原生支持异步。

CloudStorageAccount storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageAccountConnectionString"));
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference("container1");
CloudBlockBlob blockBlob = container.GetBlockBlobReference("blob1.txt");

await blockBlob.DownloadToStreamAsync(context.Response.OutputStream);

1
WindowsAzure.Storage 2.1.0.0-rc现在原生支持异步操作 - http://www.nuget.org/packages/WindowsAzure.Storage - Alex S
1个回答

2
您当前的解决方案是异步的,并且将释放服务器请求线程。请参见我对您另一个问题的回答,了解有关TaskFactory.FromAsync的建议。

是否可以保持blob压缩(GZIP),并使用Content-Encoding:gzip使客户端解压缩它们?

我不知道。这是一个有趣的问题,您可以将其发布为单独的问题。

关于您关于GZIP压缩blob的问题,答案是肯定的。我自己尝试过使用较小的文件(如JS、图像等),在我尝试的各种浏览器中都可以正常工作。不确定在读取部分数据并将其刷新到流中而不是流整个blob的情况下它会如何工作。 - Gaurav Mantri
@GauravMantri:所以您只需手动设置标头,然后将预先压缩的文件流式传输即可,这样就可以正常工作了? - Stephen Cleary
1
我所做的方法是将blob的Content-Encoding属性设置为gzip,并且当直接从存储中流式传输时,一切都运行得非常完美。 - Gaurav Mantri
客户端当前不支持压缩。您当然可以设置头文件,大多数浏览器都会遵守它,但是如果通过客户端下载,您将检索到已压缩的内容而不是未压缩的数据。这是我们正在跟踪的一个功能请求。 - Joe Giardino

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接