10

我正在实现我自己的异步 HTTP 处理程序,HttpTaskAsyncHandler并使用 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);
4

1 回答 1

2

您当前的解决方案是异步的,将释放服务器请求线程。有关建议,请参阅我对您的其他问题的回答TaskFactory.FromAsync

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

我不知道。这是一个有趣的问题;您可能想将其作为一个单独的问题发布。

于 2013-08-14T02:15:20.753 回答