2017-03-27 131 views
0

目前我进入异步/等待的关键字,并通过以下几个问题去:When correctly use Task.Run and when just async-awaitAsync/Await vs Threads请等待后台线程?

然而,即使第二个链接不回答我的问题,这是当简单地使用

Task.Run(...) 

await Task.Run(...) 

它是情境或者是有通过使用的await(从而返回给调用)来获得什么?

+5

像任何其他使用任务一样,不等待会导致任务被触发并立即继续执行当前方法,等待时将返回一个任务并将该方法的其余部分连接为一个延续(有效地停止执行直到任务完成)。你想达到什么目的? –

+0

@AntP由于我对这些关键字不太熟悉,我只是想了解是否使用await创建后台线程而不是直接触发它们,或者如果使用await Task.Run(。 ..)更具情境性,那么,我应该在什么情况下做呢? – Iason

+0

这两件事产生不同的行为,所以它是情境 - 如果你想返回一个不完整的'任务',可以在堆栈上进一步等待(例如附加额外的延续,处理失败......),你需要等待(或返回)由Task.Run返回的任务。如果你想解雇任务而忘了它,你不想等待它。 –

回答

4

代码Task.Run(...)(在均为示例)将委托发送到线程池并返回将包含该委托结果的任务。这些“结果”可以是实际的返回值,也可以是例外。您可以使用返回的任务来检测结果何时可用(即代表何时完成)。

所以,你应该使用的Task如果以下任为真:

  • 您需要在操作完成检测并以某种方式作出回应。
  • 您需要知道操作是否成功完成。
  • 您需要处理操作中的异常。
  • 你需要做一些操作的返回值。

如果你调用代码需要做任何的那些,然后使用await

await Task.Run(...); 

具有长期运行的后台任务,有时你想要做的那些(例如,检测例外),但你不想做马上;在这种情况下,只需保存Task然后await它在你的应用程序的一些其他问题:

this.myBackgroundTask = Task.Run(...); 

如果不需要上述的任何,那么你可以做一个“射后不理” ,因为这样的:

var _ = Task.Run(...); // or just "Task.Run(...);" 

需要注意的是真正的“射后不理”的应用是极为罕见。这实际上是说“运行这个代码,但我不在乎它是否完成,何时完成,或者它是否成功”。

1

当使用fire和forget类型处理逻辑时,您可以使用Task.Run(),类似于在某人订阅它们时调用事件。您可以使用此日志记录,通知等

如果你依赖的结果,或在你的方法执行的操作,你需要使用等待Task.Run(),因为它暂停当前执行,直到你的任务完成。