异步/等待与线程


100

Microsoft在.Net 4.5中添加了新Async/Await功能,以简化异步编码。但是,我想知道

  1. 可以Async/Await完全取代旧的使用方式 Threads吗?
  2. 是否可以异步Async/Await执行任何Thread操作?
  3. 可以Async/Await只与像一些方法来使用WebClient.DownloadStringAsync或者我可以将任何同步方法,使其使用Async/Await和不阻塞主线程?

2
线程和异步/等待是不相关的功能。您可以将它们组合在一起,但不必这样做。
dtb

2
我以为Async / Await正在执行与正在执行的相同的操作new Thread(() => {Some Work}).Start();?!是不是?
罗曼·拉斯基

2
不。您的假设不正确。您可能正在考虑Task.Run(TPL),它通常与Async / Await结合使用,但也无关,也不必与之一起使用。
dtb

4
@dtb:那么什么时候使用Async / Await和什么时候使用Threads?。我对Task.Run,​​Thread.Start,Async / Await之间的区别感到非常困惑。如果您能为我提供一个很好的解释,让我理解它们之间的区别,我将非常感激
Roman Ratskey 2013年

2
异步/等待不会创建或以任何其他方式使用线程。
wRAR 2013年

Answers:


78

它可以完全替代使用线程的旧方法吗?

不。线程可以做更多有用的事情。Await是专门为处理耗时的事情而设计的,通常是一个I / O请求。传统上,这是在I / O请求完成时通过回调完成的。编写依赖于这些回调的代码非常困难,请等待将其大大简化。

能够完成Thread可以异步完成的工作吗?

大致。Await只是负责处理延迟,否则它不会做线程做的任何事情。await 表达式位于await关键字的右边,它是完成任务的方法。理想情况下,它根本不使用线程,它发布驱动程序请求,并且一旦驱动程序完成数据传输,它就会生成一个完成通知回调。到目前为止,网络是最常见的用法,延迟通常为数百毫秒,并且服务从桌面或LAN迁移到“云”中不可避免地会产生副作用。同步使用此类服务​​会使UI毫无响应。

仅可与某些方法(例如WebClient.DownloadStringAsync)一起使用

不能。您可以将其与任何返回Task的方法一起使用。XxxxAsync()方法只是.NET框架中预煮的方法,用于需要一些时间的常见操作。就像从Web服务器下载数据一样。


4
在现代C#方面,什么是在外部API上实现异步回调的最佳方法?
bonCodigo 2014年

5
在最后一段中介绍了使用任务。
汉斯·帕桑

我希望一个线程可以做的事情不能通过异步编程来完成。
Saeed Neamati '16

1
您是否可以扩展“线程可以做更多有用的事情”?了解线程所提供async的不适合的功能将很有用。
约翰

1
值得一提await Task.Run的cpu绑定工作。如果我理解正确,那么有时可以完成创建线程或后台工作人员要执行的操作。
制造商史蒂夫

15

对此的官方声明。尽管在盲目地将一件事替换为另一件事之前,您应该了解线程和异步编程之间的区别。


这就像我读到的第一个简洁明了的关于线程和异步/等待的资源。
Arman Bimatov 2015年

2
该答案仅包含文档的链接。由于链接可能会过时,答案也可能会过时-甚至更糟-完全无用。我们鼓励Stack用户将链接的相关部分直接发布到他们的问题中。
HimBromBeere

1
遗憾的是,官方声明并未解释何时进行await Task.Run。简要介绍了Task.Run,​​但尚不清楚。最重要的是,await它本身不会使cpu绑定的任务并行运行,因此应通过进行此工作await Task.Run
制造商史蒂夫(Steve)

1

我是这样想的(如果您查看https://docs.microsoft.com/zh-cn/previous-versions/visualstudio/visual-studio-2012/hh191443(v=vs.110 #threads

异步/等待是一种在主应用程序线程上运行某些代码的快速方法,其优势在于,代码可以在没有工作要做时挂起自身,将焦点返回到主线程,然后在出现主线程时“唤醒”主线程。是要获得的结果,然后将处理传递回主线程(您猜对了)。可以将其视为Basic中基于事件的GOTO语句,该语句可以将控制往返传递到特定的执行行。

相反,线程是一个独立的执行流,可以使用自己的变量等运行。在给定足够硬件的情况下,执行与主线程并行进行。

如果您有一个GUI应用程序,该应用程序将下载一个文件,然后在下载文件时对其进行处理-我将使用async / await方法来实现该功能。

但是,如果您的GUI需要下载5000个文件-我将创建一个文件下载线程来处理该问题,因为在执行转移以下载文件时,主GUI线程可能会冻结。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.