何时使用Task.Run,​​何时使用async-await以及何时组合使用它们

时间:2016-06-13 09:06:48

标签: c# multithreading asynchronous

我阅读过很多帖子,但仍无法区分所有这些帖子。我所能理解的是Task.Run将调用后台线程。 async- await是异步编程。

Task.Run是否意味着后台线程将表现为阻塞线程?

尝试从互联网下载多个大图片。我应该如何组合使用这些关键字?为什么?

2 个答案:

答案 0 :(得分:3)

  

何时使用Task.Run,​​何时使用async-await以及何时组合使用

我有entire blog series on the subject,但总结如下:

  • 使用Task.Run从具有UI的应用程序的UI线程移动CPU绑定(或阻止)工作。
  • 使用async / await进行I / O绑定工作。

有一些更为罕见的情况Task.Runasync可能有用,但上述两点为大多数情况提供了指导。

  

Task.Run是否意味着后台线程将表现为阻塞线程?

Task.Run实际上可以同步或异步运行,但它确实使用了线程池线程。

  

我正在尝试在.net 4.5

中创建桌面控制台应用程序      

尝试从互联网下载多个大图片。我应该如何组合使用这些关键字?为什么?

这是非UI应用中的I / O绑定操作,因此您绝对应该更喜欢async / await

答案 1 :(得分:0)

你可以打电话给

await Task.Run(DownloadImageMethod);

下载图像时不会阻止调用线程,下载完成后将继续执行以下代码。

Task.Run(DownloadImageMethod);

这样在下载图像时不会阻塞你的调用线程,但是会在下面的代码中继续执行。在执行下一个方法/命令之前,这不会等待下载完成。

在SO上查看类似的问题例如:

Aync/Await action within Task.Run()

TLDR;

Task.Run将创建新线程并启动它。该线程将异步运行。

如果您希望线程同步运行,则无法在其上调用Task.Wait()方法。

如果您希望线程以异步方式运行但假装它是同步的,则可以在其前面放置awaitawait Task.Run(...))。这将允许您以顺序方式编写代码,而不必处理回调。

当您使用Task.Run启动新线程时,该线程将释放您当前的线程,您可以在其中执行其他工作。我不知道这对你的控制台应用程序有什么帮助。

很好的例子是桌面和移动应用程序中的UI线程,其中渲染是在UI线程上完成的,并且您不希望在下载图像时阻止UI线程执行其操作。

在这种情况下,await Task.Run(...)将启动另一个线程,继续处理UI线程上的其他工作,当任务完成时,返回到UI线程,您可以在其中操作控件并更新UI相关属性。

- 编辑

仅在必要时使用Task.Run - 仅当您在Task.Run内调用的方法运行时间超过0.5秒时才使用07/11/2014。这将阻止应用程序在执行IO操作时“冻结”。