繁体   English   中英

使用 Task 编写异步代码和使用 async await 编写异步代码之间的区别?

[英]Difference between writing Asynchronous Code with Task and Asynchronous Code with async await?

我有一个关于异步编程的问题:

带有任务的异步代码(没有 async/await)和带有 async/await 的异步代码有什么区别?

在 C# 中,我们可以使用 Task 编写异步代码或方法,也可以使用关键字。


带任务的异步代码(无 Async/Await)

static Task DoWorkAsync()
{
    var work = Task.Run(() => { Thread.Sleep(5000); });
    var workcompleted = work.ContinueWith((x) => { Console.WriteLine("Work Completed!!!"); });
    return work;
}

带有 Async/Await 的异步代码

    static async Task DoWorkAsync()
    {
        await Task.Run(() => { Thread.Sleep(10000); });
        Console.WriteLine("Work Completed");
    }

如果回答我的问题,我真的很感激。

在 C# 中,我们可以使用 Task 编写异步代码或方法,也可以使用关键字。

这在技术上是正确的,但是在没有async / await的情况下编写异步代码要正确地完成要困难得多。 考虑您拥有的代码示例:

static Task DoWorkAsync()
{
    var work = Task.Run(() => { Thread.Sleep(5000); });
    var workcompleted = work.ContinueWith((x) => { Console.WriteLine("Work Completed!!!"); });
    return work;
}

上面的代码使用了具有 危险默认行为的低级ContinueWith方法。 具体来说,它将隐式捕获当前的TaskScheduler

上面的代码返回一个在Task.Run委托完成时完成的Task 当该任务完成时, ContinueWith委托尚未运行,并且由于workcompleted被忽略,因此来自ContinueWith委托的任何异常都将被丢弃。 调用代码无法知道ContinueWith委托何时完成,或者它是否成功完成。

对比async / await代码,它更短、更清晰、更容易维护、更正确:

static async Task DoWorkAsync()
{
    await Task.Run(() => { Thread.Sleep(10000); });
    Console.WriteLine("Work Completed");
}

上面的代码返回一个Task ,当整个DoWorkAsync完成时完成(包括WriteLine )。 任何异常都会被捕获并放置在任务上。

此外,更复杂的逻辑(例如循环和重试)更自然地使用async / await表达,而不是使用手动管理的 state 对象的延续。

在后台, DoWorkAsync中的await最终会调用ContinueWith 通过让编译器正确生成棘手的代码,您可以避开许多陷阱并最终得到更易于维护的代码。

暂无
暂无

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

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