首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >异步下载blobs

异步下载blobs
EN

Code Review用户
提问于 2016-10-29 16:53:24
回答 2查看 3.5K关注 0票数 7

我们有一个工作实现,执行I/O操作,从Azure Blob存储以异步/等待方式从Blob返回数据。

代码语言:javascript
复制
//Method1 is not async, this is what is called from the controller
public IEnumerable<Data> Method1()
{
    //Running the async method and returning the result from task
    return Task.Run(() => GetDataAsync()).Result;
}


private async Task<IEnumerable<Data>> GetDataAsync()
{
    //There are multiple blob address where the data is held. The code creates, in parallel multiple tasks for each address.
    //It returns tasks that will be run in Async pattern
    var tasks = multipleBlobAddress.AsParallel.Select(blobAddress =>{
            Task<IEnumerable<Data>> task = GetDataFromBlobsAsync(blobAddress);
            return task;
    });

    //Awaits all tasks to complete
    var completedTasks = await Task.WhenAll<IEnumerable<Data>>(tasks);
    //Selects all the tasks and returns them. Each tasks has data.
    return completedTasks.SelectMany(t => t);
}

private Task<IEnumerable<Data>> GetDataFromBlobsAsync(string address)
{
    //Opens the blob and reads from it
    using (var blobStream = blobService.OpenRead(address))
    {
        //Deserialises the data read from the blob
        data = service.DeserialiseData(blobStream);
    }

    return Task.FromResult<IEnumerable<Data>>(data);
}

我们已经了解到,从blobs读取数据的最佳方法是遵循异步/等待模式,而不是使用AsParallel方法(其他建议最受欢迎)。我有以下问题:

  1. 通过并行地创建任务,然后等待它们全部完成,我们会失去任何性能吗?
  2. 我们有哪些明显的地方是错误的,或者我们可以改进和潜在地提高性能,或者使代码更好地维护/读取?
  3. 我们是否正确地遵循异步/等待模式?

如果您需要有关代码的任何额外信息,我将很高兴地提供它,并希望使它更清楚。

EN

回答 2

Code Review用户

回答已采纳

发布于 2016-11-01 14:58:11

从来没有必要这样做:

代码语言:javascript
复制
return Task.Run(() => GetDataAsync()).Result;

为什么要启动一个新任务,然后与.Result同步等待?当您发现同步上下文可能导致死锁时,这是一种代码,稍后会咬您一口。请参阅关于异步死锁主题的斯蒂芬·克利里的博客文章。斯蒂芬的博客绝对是aysncawait信息的宝库。

要么使用同步api (从控制器一直到Azure ),要么使用异步api(使用asyncawait)。不要混为一谈--这是错误的来源,也是毫无意义的。当线程可能做其他事情时,Aysnc是有用的。例如,在一个为请求提供服务的web应用程序中。如果web应用程序被.ResultWait阻塞,那么就没有好处,您应该使用同步API。

票数 6
EN

Code Review用户

发布于 2016-11-01 13:54:16

先回答问题,

  1. 当重复执行相同的代码时,运行并行是为了提高效率和速度。
  2. 您可能会因为没有注意常见的线程问题而错误地进行线程处理。Msdn链接有一些好的通用建议Msdn链接有一些好的通用建议.
  3. 不完全是,异步和等待与您可能认为的并行是不一样的,关于Pluralsight有一门很好的课程,它解释了它是什么以及它是如何正确实现的。-我不确定我是否能提供一个链接,主持人能让我知道吗?

两者的不同之处在于并行/线程执行的代码相同,但参数不同。

异步等待是一种让计算机决定停止工作当前进程的机制,等待,因为响应当时还没有准备好。电脑可以去做别的事情。返回异步结果后,计算机将返回并继续运行。基本上不要阻塞主线程。

好的,看看您的代码,删除method1并使用异步,然后等待所有的代码。

我试图更改您的代码,但由于代码不完整,我只能尝试为您填补空白。

代码语言:javascript
复制
public async Task<IEnumerable<Data>> GetDataAsync()
{
    //There are multiple blob address where the data is held. The code creates, in parallel multiple tasks for each address.
    //It returns tasks that will be run in Async pattern
    var tasks = multipleBlobAddress.AsParallel.Select(async blobAddress =>
    {
        IEnumerable<Data> task = await GetDataFromBlobsAsync(blobAddress);
        return task;
    });

    //Awaits all tasks to complete
    var completedTasks = await Task.WhenAll((IEnumerable<Data>)(tasks));
    //Selects all the tasks and returns them. Each tasks has data.
    return completedTasks.SelectMany(t => t);
}

private async Task<Data> GetDataFromBlobsAsync(string address)
{
    //Opens the blob and reads from it
    using (var blobStream = await blobService.OpenRead(address)) // at the bottom there should be a Async method
    {
        //Deserialises the data read from the blob
        data = service.DeserialiseData(blobStream);
    }

    return data;
}
票数 4
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/145611

复制
相关文章

相似问题

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