在使用带有`Task.Run()`冗余的`异步lambda? [英] is using an an `async` lambda with `Task.Run()` redundant?
问题描述
我刚遇到一些代码,例如:
var task = Task.Run(async()=> {等待Foo.StartAsync();});
task.Wait();
(不,我不知道 Foo的内部工作原理。 StartAsync()
)。我最初的反应是摆脱 async
/ await
并重写为:
var任务= Foo.StartAsync();
task.Wait();
是否正确(再次,对一无所知Foo.StartAsync()
)。 此对有什么区别-使用Task.Run ... 运行异步动作委托表示在某些情况下可能有意义,但是它还说说实话,我还没有看到很多情况……
通常, Task.Run
的预期用法是执行CPU约束的非UI线程上的代码。因此,它很少与 async
委托一起使用,但是有可能(例如,对于具有异步部分和CPU绑定部分的代码)
但是,这是预期的用法。我认为在您的示例中:
var task = Task.Run(async()=> {等待Foo.StartAsync() ;});
task.Wait();
原作者更有可能试图同步阻塞异步代码,并且( )使用 Task.Run
到避免在这种情况下常见的死锁(正如我在博客中所描述的)。
从本质上讲,它看起来像线程池我在有关棕地异步代码的文章中描述的黑客。。 p>
最好的解决方案是不使用 Task.Run
或 等待
:
等待Foo.StartAsync();
这将导致 async
通过您的代码库,这是最好的方法,但现在可能会给开发人员带来大量工作。这大概就是为什么您的前任使用 Task.Run(..)。Wait()
。
的原因
I just came across some code like:
var task = Task.Run(async () => { await Foo.StartAsync(); });
task.Wait();
(No, I don't know the inner-workings of Foo.StartAsync()
). My initial reaction would be get rid of async
/await
and rewrite as:
var task = Foo.StartAsync();
task.Wait();
Would that be correct, or not (again, knowing nothing at all about Foo.StartAsync()
). This answer to What difference does it make - running an 'async' action delegate with a Task.Run ... seems to indicate there may be cases when it might make sense, but it also says "To tell the truth, I haven't seen that many scenarios ..."
Normally, the intended usage for Task.Run
is to execute CPU-bound code on a non-UI thread. As such, it would be quite rare for it to be used with an async
delegate, but it is possible (e.g., for code that has both asynchronous and CPU-bound portions).
However, that's the intended usage. I think in your example:
var task = Task.Run(async () => { await Foo.StartAsync(); });
task.Wait();
It's far more likely that the original author is attempting to synchronously block on asynchronous code, and is (ab)using Task.Run
to avoid deadlocks common in that situation (as I describe on my blog).
In essence, it looks like the "thread pool hack" that I describe in my article on brownfield asynchronous code.
The best solution is to not use Task.Run
or Wait
:
await Foo.StartAsync();
This will cause async
to grow through your code base, which is the best approach, but may cause an unacceptable amount of work for your developers right now. This is presumably why your predecessor used Task.Run(..).Wait()
.
这篇关于在使用带有`Task.Run()`冗余的`异步lambda?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!