我正在尝试使用 .NET 4.5 async & await实现完全异步的 blob 下载。
假设整个 blob 可以立即放入内存中,并且我们希望将其保存在string
.
代码:
public async Task<string> DownloadTextAsync(ICloudBlob blob)
{
using (Stream memoryStream = new MemoryStream())
{
IAsyncResult asyncResult = blob.BeginDownloadToStream(memoryStream, null, null);
await Task.Factory.FromAsync(asyncResult, (r) => { blob.EndDownloadToStream(r); });
memoryStream.Position = 0;
using (StreamReader streamReader = new StreamReader(memoryStream))
{
// is this good enough?
return streamReader.ReadToEnd();
// or do we need this?
return await streamReader.ReadToEndAsync();
}
}
}
用法:
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageAccountConnectionString"));
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference("container1");
CloudBlockBlob blockBlob = container.GetBlockBlobReference("blob1.txt");
string text = await DownloadTextAsync(blockBlob);
这段代码是否正确,并且确实是完全异步的?你会以不同的方式实现吗?
我将不胜感激一些额外的澄清:
GetContainerReference
并且GetBlockBlobReference
不需要异步,因为他们还没有联系服务器,对吧?是否
streamReader.ReadToEnd
需要异步?我对什么有点困惑
BeginDownloadToStream
..到EndDownloadToStream
被调用时,我的内存流中是否包含所有数据?还是流只打开预读?
更新:(从 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");
string text = await blockBlob.DownloadTextAsync();