首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用产量延迟Azure blob存储调用- c#

使用产量延迟Azure blob存储调用- c#
EN

Stack Overflow用户
提问于 2018-10-10 16:12:50
回答 1查看 353关注 0票数 2

我现在有一种方法,可以从Azure中提取blob文件名的列表。该方法如下:

代码语言:javascript
复制
internal async Task<IEnumerable<BlobItem>> GetFiles(CloudBlobContainer container, string directoryName, bool recursive)
{
    var results = new List<BlobItem>();
    BlobContinuationToken continuationToken = null;

    do
    {
        var response = await container.GetDirectoryReference(directoryName).ListBlobsSegmentedAsync(false, BlobListingDetails.None, 100, continuationToken, null, null);

        continuationToken = response.ContinuationToken;
        foreach (var item in response.Results)
        {
            if (item.GetType() != typeof(CloudBlobDirectory))
                results.Add(new BlobItem(item));
            else if (recursive)
                results.AddRange(await GetFiles(container, ((CloudBlobDirectory)item).Prefix, recursive));
        }
    }
    while (continuationToken != null);

    return results;
}

我不喜欢上面的代码,我运行所有文件并添加到结果,直到取消令牌为空。所以基本上,去得到所有,然后停下来,然后回来。

我不认为这是过于有效-我想我可能会产生结果,所以它只会得到下一批的结果,当我准备好了(从调用代码)。

我不太熟悉使用收益率,并提出了这一点,但我认为这可能不是推迟对ListBlobSegment的调用。这是我的密码:

代码语言:javascript
复制
internal IEnumerable<BlobItem> GetFiles(CloudBlobContainer container, string directoryName, bool recursive)
{
    var results = new List<BlobItem>();
    BlobContinuationToken continuationToken = null;

    do
    {
        var response = container.GetDirectoryReference(directoryName).ListBlobsSegmentedAsync(false, BlobListingDetails.None, 100, continuationToken, null, null).GetAwaiter().GetResult();

        continuationToken = response.ContinuationToken;
        foreach (var item in response.Results)
        {


            if (item.GetType() != typeof(CloudBlobDirectory))
                yield return new BlobItem(item);
            else if (recursive)
            {
                var internalResponse =  GetFiles(container, ((CloudBlobDirectory)item).Prefix, recursive));
                foreach (var intItem in internalResponse)
                {
                    yield return intItem;
                }
            }
        }
    }
    while (continuationToken != null);
}

如果我用正确的方式使用yield语句,有人能告诉我吗?如前所述,以前从未在愤怒中使用过这种方法,并且希望能够正确地使用它:-)我的目标是希望推迟服务调用,并提高调用的代码效率。

提前感谢您的指点!

注意:使用这些API来存储blob

代码语言:javascript
复制
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-10-10 20:10:46

编辑2018-11-15C#8开始,您将能够使用IAsyncEnumerable

代码语言:javascript
复制
async IAsyncEnumerable<int> GetBigResultsAsync()
{
    await foreach (var result in GetResultsAsync())
    {
        if (result > 20) yield return result; 
    }
}

IAsyncEnumerable<string> GetAsyncAnswers()
{
    return AsyncEnum.Enumerate<string>(async consumer =>
    {
        foreach (var question in GetQuestions())
        {
            string theAnswer = await answeringService.GetAnswer(question);
            await consumer.YieldAsync(theAnswer);
        }
    });
}

https://blogs.msdn.microsoft.com/dotnet/2018/11/12/building-c-8-0/

https://archive.codeplex.com/?p=asyncenum

原始答案

在这种情况下,您需要使用IObservable<BlobItem>而不是IEnumerable<BlobItem>。至少在内部,这取决于您实际如何调用GetFiles

这个问题有一些很好的解释,你应该研究一下:

如何在执行Task.WhenAny时生成返回项

或接受答案的相应的博客文章

附带注意:您可能希望将参数useFlatBlobListing=true用于ListBlobsSegmentedAsync,而不是手动执行递归代码。

一些快速代码,描述了这看起来可能是什么样子(没有测试或任何东西)

代码语言:javascript
复制
public IEnumerable<BlobItem> GetFilesAsEnumerable(CloudBlobContainer container, string directoryName, bool recursive)
{
    return GetFiles(container, directoryName, recursive).ToEnumerable();
}

public IObservable<BlobItem> GetFiles(CloudBlobContainer container, string directoryName, bool recursive)
{
    return Observable.Create<BlobItem>(async obs =>
        {
            BlobContinuationToken continuationToken = null;

            do
            {
                var response = await container.GetDirectoryReference(directoryName).ListBlobsSegmentedAsync(/*useFlatBlobListing*/ recursive, BlobListingDetails.None, 100, continuationToken, null, null);

                continuationToken = response.ContinuationToken;
                foreach (var item in response.Results)
                {
                    // Only required if recursive == false
                    if (item.GetType() != typeof(CloudBlobDirectory))
                        obs.OnNext(new BlobItem(item));
                }
            }
            while (continuationToken != null);
        });
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52744608

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档