在使用带有`Task.Run()`冗余的`异步lambda? [英] is using an an `async` lambda with `Task.Run()` redundant?

查看:91
本文介绍了在使用带有`Task.Run()`冗余的`异步lambda?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚遇到一些代码,例如:

  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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆