【发布时间】:2017-12-27 04:32:28
【问题描述】:
假设我有一个函数Task UploadAsync(Stream stream) 将一些数据上传到远程机器。调用此函数将使 async 关键字传播到整个调用树。另一种方法是将它包装在 Task.Run 中,有点像 Fire and forgot 方式:
void DoUpload(Stream stream) {Task.Run(async () => await UploadAsync(stream)})}
我从 Stephen Cleary 的blog 中读到说 Task.Run 应该只用于 CPU 绑定操作,显然上传数据块不受 CPU 限制。所以在这里,如果我在Task.Run 内调用await UploadAsync(stream) 似乎是错误的方式。
所以我的问题是,使用 Task.Run 包装和调用异步函数是一种不好的做法吗?
【问题讨论】:
-
您要等
UploadAsync(stream)完成吗?顺便说一句,Task.Run将返回Task和UploadAsync(stream)- 将返回Task。那么,你有什么不同?为什么你需要Task.Run? -
您是想异步运行它然后忘记它,还是等到任务完成?在后一种情况下,只需调用
Task task = UploadAsync(stream)然后task.Wait()等待它完成。 -
Another way is to wrap it in Task.Run, kind of Fire and forgot way:如果您实际上只想触发它并忘记它,则根本没有理由将代码包装在Task.Run中。这增加了很多开销而没有任何回报。也就是说,一开始就解雇并忘记类似的事情几乎肯定是错误的。 -
“使用 Task.Run 包装和调用异步函数是一种不好的做法吗?” - 什么是“不好的做法”主要是见仁见智。我同意其他cmets,这在您的情况下毫无意义。但它是有害还是错误?这充其量取决于您未提供的上下文,并且在大多数情况下,这只是一个意见问题。毕竟,如果你要让
Task.Run()任务忽略返回的任务,你还不如自己忽略它(这很容易)。
标签: c# asynchronous