【问题标题】:Call multiple async methods that rely on each other调用多个相互依赖的异步方法
【发布时间】:2019-02-21 02:45:51
【问题描述】:

我正在寻找有关调用多个异步方法的最佳实践,其中每个下一个方法都依赖于前一个方法返回的值。

我正在尝试两种方法

1) https://dotnetfiddle.net/waPL9L

public async void Main()
    {       
        var T1 = await Sum(2,5);
        var T2 = await Sum(T1, 7);
        var T3 = await Sum(T2, 7);      

        Console.WriteLine(T3);
    }

    public async Task<int> Sum(int num1, int num2){
        return await Task.Run(() => {
            // for some reason if i use Sleep... I don't see any results at all...
            //Thread.Sleep(2000);
            return num1 + num2;
        });
    }

2) https://dotnetfiddle.net/1xycWH

public async void Main()
    {
        var T1 = Sum(2,5);
        var T2 = Sum(T1.Result, 7);
        var T3 = Sum(T2.Result, 7);

        //var myVar = T3.Result;

        var listOfTasks = new List<Task>{T1,T2,T3};

        await Task.WhenAll(listOfTasks);

        Console.Write(T3.Result);
    }

    public async Task<int> Sum(int num1, int num2){
        return await Task.Run(() => {
            Thread.Sleep(1000);
            return num1 + num2;
        });
    }

只是想了解最好的方法,因为我是异步编程的新手。

提前致谢!

乔尼

【问题讨论】:

  • 无... 首先您正在使用StartNew,您可能应该使用新的Task.Run其次,您将任务包装在async方法中,不要在方法的实现中使用Task.Run;相反,使用Task.Run 调用该方法,第三您的方法都没有以 Async 为后缀,最后您正在调用 Result async 方法并且在某些情况下会出现死锁,您永远不需要这样做..
  • 当你想要的是顺序执行时,试图理解为什么你使用异步
  • 积分。实际上,我的 3 个异步方法在 2 个不同的数据库中执行了一些 Db 操作,并且每个 next 方法都依赖于之前的值......我在发布这个问题后做了更多的研究,现在我明白了如何在异步方法上调用 Result 可以导致死锁... blog.stephencleary.com/2012/07/dont-block-on-async-code.html 关于我应该如何解决这个问题的任何建议? @MichaelRandall 感谢您的时间!
  • @JonathanNiu 感谢您的宝贵时间。请看我上面的评论^
  • 这是最易读和简洁的,IMO,这是最好的方式

标签: c# asynchronous asp.net-core async-await


【解决方案1】:

我正在寻找有关调用多个异步方法的最佳实践,其中每个下一个方法都依赖于之前一个方法返回的值。

许多异步问题可以通过查看同步等价物来回答。如果所有方法都是同步的,并且每个方法都依赖于之前方法的结果,那会是什么样子?

var T1 = Sum(2,5);
var T2 = Sum(T1, 7);
var T3 = Sum(T2, 7);

那么异步等价物是:

var T1 = await SumAsync(2,5);
var T2 = await SumAsync(T1, 7);
var T3 = await SumAsync(T2, 7);

附:为了将来参考,不要插入StartNewTask.Run 作为异步代码的通用占位符;他们只是混淆了这个问题,因为他们有非常具体的用例。请改用await Task.Delay;它是异步世界的Thread.Sleep

【讨论】:

  • 我实际上正在阅读您的文章“不要阻塞异步代码”,同时在这里得到您的回复有点有趣哈哈。非常感谢您的解释 - 不知道 Task.Delay 可以等待。此外,在这些 cmets 确认方法 1 是可行的方法之后,我感觉好多了。将其标记为答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-12
  • 2017-10-04
  • 2015-12-13
  • 2020-02-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多