简体   繁体   English

上一个任务完成后调用异步方法

[英]Call async method after previous task completes

I recently learned about Task.ContinueWith and am trying to apply it to some existing code I have for better performance.我最近了解了 Task.ContinueWith 并试图将其应用于我拥有的一些现有代码以获得更好的性能。 I have something like this:我有这样的事情:

        public static async Task<TResult> DoWork<T, TResult>(T value)
        {
            var fooResult = await Foo(value);
            return await Bar<TResult>(fooResult);
        }

        private static Task<MyClass> Foo<T>(T value)
        {
            return GetMyClassFromValueAsync(value);
        }

        private static Task<TResult> Bar<TResult>(MyClass myClass)
        {
            return myClass.DoOperationAsync();
        }

and was thinking I could improve it by doing something like this instead:并认为我可以通过这样做来改进它:

        public static Task<TResult> DoWork<T, TResult>(T value)
        {
            return Foo(value).ContinueWith(fooResult => Bar<TResult>(fooResult.Result));
        }

The problem that I'm running into is that ContinueWith returns a type of Task<Task<TResult>> in this case because it wraps my async call in another task.我遇到的问题是 ContinueWith 在这种情况下返回一种Task<Task<TResult>>因为它将我的异步调用包装在另一个任务中。 The only solution I've found is to do something like this:我发现的唯一解决方案是做这样的事情:

        public static async Task<TResult> DoWork<T, TResult>(T value)
        {
            return await await Foo(value).ContinueWith(fooResult => Bar<TResult>(fooResult.Result));
        }

but that just looks wrong and forces me to await it.但这看起来不对,迫使我等待它。 Is there a better way to handle this situation?有没有更好的方法来处理这种情况?

There's also a lot happening behind the scenes with these calls, so if I'm taking the wrong approach or my intuition is leading me astray and I should stick with my original approach, please let me know why so I can learn and improve.这些电话在幕后也发生了很多事情,所以如果我采取了错误的方法或者我的直觉让我误入歧途,我应该坚持原来的方法,请告诉我原因,以便我可以学习和改进。 Thanks!谢谢!

You are very close.你很亲密。 You are missing the UnWrap method at the end.您最后缺少UnWrap方法。

public static async Task<TResult> DoWork<T, TResult>(T value)
        {
            return await await Foo(value).ContinueWith(fooResult => Bar<TResult>(fooResult.Result)).UnWrap();
        }

In reality though, what you are doing with ContinueWith is no more efficient than what you had before with the await .但实际上,您使用ContinueWith执行的操作并不比您之前使用await执行的操作更有效。 I believe the await is just syntactic sugar for ContinueWith .我相信await只是ContinueWith的语法糖。 I personally find await much easier to read.我个人觉得await更容易阅读。

You are looking to chain together promises and return the final result, there is an extension method Unwrap for this.您正在寻找将 Promise 链接在一起并返回最终结果,为此有一个扩展方法Unwrap

Example:例子:

class Program
{
    static void Main(string[] args)
    {

        var finalWork = Work().ContinueWith(work => MoreWork(work.Result)).Unwrap();
        finalWork.Wait();
        var finalWorkResult = finalWork.Result;
        Console.WriteLine(finalWorkResult);

    }

    private static Task<string> MoreWork(string s)
    {
        return Task.FromResult($"{s} done... now more work.");
    }

    private static Task<string> Work()
    {
        return Task.FromResult("Work work");
    }
}

Using ContinueWiht can be problematic and it's unnecessarily complicated. 使用ContinueWiht可能会出现问题并且不必要地复杂。

Just embrace async-await :只需拥抱async-await

public static async Task<TResult> DoWork<T, TResult>(T value)
{
    return await Bar<TResult>(await Foo(value));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM