gpt4 book ai didi

c# - 使用 .NET 4.5 async、await 将 Azure blob 异步下载到字符串

转载 作者:可可西里 更新时间:2023-11-01 08:21:23 24 4
gpt4 key购买 nike

我正在尝试使用 .NET 4.5 异步和等待实现完全异步 blob 下载。

假设整个 blob 可以一次装入内存,并且我们希望将其保存在字符串中。

代码:

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);

这段代码正确吗?这确实是完全异步的吗?您会以不同的方式实现这一点吗?

我希望得到一些额外的说明:

  1. GetContainerReferenceGetBlockBlobReference 不需要异步,因为它们尚未联系服务器,对吧?

  2. streamReader.ReadToEnd 是否需要异步?

  3. 我对 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();

最佳答案

Is this code correct and this is indeed fully asynchronous?

是的。

Would you implement this differently?

是的。特别是TaskFactory.FromAsync如果您传递 Begin ,包装器会更高效。/End方法对而不是传入现有的 IAsyncResult 。像这样:

await Task.Factory.FromAsync(blob.BeginDownloadToStream,
blob.EndDownloadToStream, memoryStream, null);

我也更喜欢将它们包装到单独的扩展方法中,这样我就可以这样调用它:

await blog.DownloadToStreamAsync(memoryStream);

请注意,客户端库的下一个版本(2.1,当前处于 RC 状态)将具有 async -就绪方法,即 DownloadToStreamAsync .

GetContainerReference and GetBlockBlobReference don't need to be async since they don't contact the server yet, right?

正确。

Does streamReader.ReadToEnd need to be async or not?

它没有(也不应该)。 Stream async 是一个有点不寻常的情况。编程。通常,如果有 async方法那么你应该在你的 async 中使用它代码,但该准则不适用于 Stream类型。原因是基数Stream类不知道其实现是同步还是异步,因此它假设它是同步的,并且默认情况下将通过在后台线程上执行同步工作来伪造其异步操作。真正的异步流(例如 NetworkStream )会覆盖它并提供真正的异步操作。同步流(例如 MemoryStream )保留此默认行为。

所以您不想调用ReadToEndAsyncMemoryStream上.

I'm a little confused about what BeginDownloadToStream does.. by the time EndDownloadToStream is called, does my memory stream have all the data inside?

是的。操作是DownloadToStream ;它会将一个 blob 下载到流中。由于您正在将 blob 下载到 MemoryStream ,当此操作完成时,blob 已完全位于内存中。

关于c# - 使用 .NET 4.5 async、await 将 Azure blob 异步下载到字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18217626/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com