蔚蓝色的斑点异步下载到字符串.NET 4.5异步,等待 [英] Asynchronous download of an Azure blob to string with .NET 4.5 async, await
问题描述
我想实现的完全异步的blob与.NET 4.5异步和放大器下载;等待着。
让我们假设整个BLOB可以容纳在内存中一次,我们要拿着它在字符串
。
code:
公共异步任务<串GT; DownloadTextAsync(ICloudBlob BLOB)
{
使用(流的MemoryStream =新的MemoryStream())
{
IAsyncResult的asyncResult = blob.BeginDownloadToStream(MemoryStream的,NULL,NULL);
等待Task.Factory.FromAsync(asyncResult,(R)=> {blob.EndDownloadToStream(R);});
memoryStream.Position = 0; 使用(StreamReader的StreamReader的=新的StreamReader(MemoryStream的))
{
//这是不够好?
返回streamReader.ReadToEnd(); //还是我们需要这个?
返回等待streamReader.ReadToEndAsync();
}
}
}
用法:
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting(StorageAccountConnectionString));
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer容器= blobClient.GetContainerReference(container1);
CloudBlockBlob blockBlob = container.GetBlockBlobReference(blob1.txt);字符串文本=等待DownloadTextAsync(blockBlob);
这是code正确的,这确实是完全异步?你会不同的方式实现这一点?
我倒是AP preciate一些额外的说明:
-
GetContainerReference
和GetBlockBlobReference
不必是异步,因为他们不联系服务器然而,对吧? -
确实
streamReader.ReadToEnd
必须是异步或不? -
我有点困惑的时候是什么
BeginDownloadToStream
确实..EndDownloadToStream
被称为,我的内存流有内部的所有的数据?或只开放pre读取流?
更新:(作为存储2.1.0.0 RC)
异步现在支持原生。
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting(StorageAccountConnectionString));
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer容器= blobClient.GetContainerReference(container1);
CloudBlockBlob blockBlob = container.GetBlockBlobReference(blob1.txt);字符串文本=等待blockBlob.DownloadTextAsync();
这是code正确的,这确实是完全异步的?
块引用>是
你不同的方式实现这一点?
块引用>是的。尤其是,
TaskFactory.FromAsync
包装是更有效的,如果你在一个通过开始
/结束
方法对强似在现有的的IAsyncResult
。像这样的:等待Task.Factory.FromAsync(blob.BeginDownloadToStream,
blob.EndDownloadToStream,MemoryStream的,NULL);我也preFER把它们包装成单独的扩展方法,所以我可以这样调用它:
等待blog.DownloadToStreamAsync(MemoryStream的);
请注意,该客户端库的下一个版本(2.1,目前在RC)将有
异步
-ready方法,即DownloadToStreamAsync
。
GetContainerReference和GetBlockBlobReference不必是异步,因为它们不在服务器联系呢,对吧?
块引用>正确的。
请问streamReader.ReadToEnd都需要进行异步或不?
块引用>它没有(也不应该)。
流
是有点不寻常的情况下与异步
节目。通常情况下,如果有一个异步
方法,那么你应该在你的异步
code使用它,但该准则没有按T持有流
类型。其原因是,该基地流
类不知道它的实现是同步的还是异步的,因此它假定它是同步的,在默认情况下将假冒其通过只是在做异步操作在后台线程同步工作。真正的异步流(例如,的NetworkStream
)覆盖此,并提供真正的异步操作。同步流(例如,的MemoryStream
)保持这个默认的行为。所以你的不的要调用
ReadToEndAsync
在的MemoryStream
。
我有点无所适从BeginDownloadToStream由EndDownloadToStream被调用的时候呢..,做我的记忆流里面有所有的数据?
块引用>是的。操作
DownloadToStream
;它,它会下载一个blob成流。既然你正在下载一个blob成的MemoryStream
,团块完全是在内存中完成此操作的时间。I'm trying to implement a fully asynchronous blob download with .NET 4.5 async & await.
Let's assume the entire blob can fit in memory at once, and we want to hold it in a
string
.Code:
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(); } } }
Usage:
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);
Is this code correct and this is indeed fully asynchronous? Would you implement this differently?
I'd appreciate some extra clarifications:
GetContainerReference
andGetBlockBlobReference
don't need to be async since they don't contact the server yet, right?Does
streamReader.ReadToEnd
need to be async or not?I'm a little confused about what
BeginDownloadToStream
does.. by the timeEndDownloadToStream
is called, does my memory stream have all the data inside? or is the stream only open pre read?Update: (as of Storage 2.1.0.0 RC)
Async now supported natively.
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();
解决方案Is this code correct and this is indeed fully asynchronous?
Yes.
Would you implement this differently?
Yes. In particular, the
TaskFactory.FromAsync
wrappers are much more efficient if you pass in aBegin
/End
method pair instead of passing in an existingIAsyncResult
. Like this:await Task.Factory.FromAsync(blob.BeginDownloadToStream, blob.EndDownloadToStream, memoryStream, null);
I also prefer to wrap these up into separate extension methods so I can call it like this:
await blog.DownloadToStreamAsync(memoryStream);
Note that the next version of the client libraries (2.1, currently in RC) will have
async
-ready methods, i.e.,DownloadToStreamAsync
.GetContainerReference and GetBlockBlobReference don't need to be async since they don't contact the server yet, right?
Correct.
Does streamReader.ReadToEnd need to be async or not?
It does not (and should not).
Stream
is a bit of an unusual case withasync
programming. Usually, if there's anasync
method then you should use it in yourasync
code, but that guideline doesn't hold forStream
types. The reason is that the baseStream
class doesn't know whether its implementation is synchronous or asynchronous, so it assumes that it's synchronous and by default will fake its asynchronous operations by just doing the synchronous work on a background thread. Truly asynchronous streams (e.g.,NetworkStream
) override this and provide true asynchronous operations. Synchronous streams (e.g.,MemoryStream
) keep this default behavior.So you don't want to call
ReadToEndAsync
on aMemoryStream
.I'm a little confused about what BeginDownloadToStream does.. by the time EndDownloadToStream is called, does my memory stream have all the data inside?
Yes. The operation is
DownloadToStream
; that it, it downloads a blob into a stream. Since you are downloading a blob into aMemoryStream
, the blob is entirely in memory by the time this operation completes.这篇关于蔚蓝色的斑点异步下载到字符串.NET 4.5异步,等待的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!