简体   繁体   English

我应该用Task.Run包装慢速调用吗?

[英]Should I wrap slow calls with Task.Run?

I have this ASP MVC call which is aync because of an async call it needs to make. 我有这个ASP MVC调用,它是异步,因为它需要进行异步调用。 I noticed there are a couple of slow sync calls (eg db access). 我注意到有几个慢同步调用(例如数据库访问)。 The method needs to have all returned data available in order to proceed. 该方法需要具有所有可用的返回数据才能继续。

I thought of wrapping the sync calls with Task.Run and await for all of them. 我想用Task.Run包装同步调用并等待所有这些调用。

Does it make sense to wrap the slow sync calls? 包装慢同步调用是否有意义? What if there was only sync calls? 如果只有同步通话怎么办?

Don't use Task.Run to parallelize work in the server-side code, unless the number of client requests you expect to serve concurrently is really low. 不要使用Task.Run并行化服务器端代码中的工作,除非您希望同时服务的客户端请求数量非常少。 Otherwise, you might speed up the processing of an individual request, but you'll hurt scalability of your web app for when there are many users. 否则,您可能会加快单个请求的处理速度,但是当有很多用户时,您的Web应用程序的可扩展性会受到影响。

To try and extend @Noseratio, spinning up thread to "speed up" sync work scales terribly bad. 为了尝试扩展@Noseratio,将线程旋转到“加速”同步工作非常糟糕。

An important thing to remember is that using Task.Run inside ASP.NET is extremely dangerous because the runtime isn't aware you queued work which needs to be done and IIS may attempt to recycle you app from time to time which will cause work to abrupt unintentionally. 要记住的一件重要事情是在ASP.NET中使用Task.Run是非常危险的,因为运行时不知道你需要完成的排队工作,IIS可能会不时地尝试回收你的应用程序,这将导致工作无意中突然。

If you're using .NET Framework 4.5.2 there is a solution via HostingEnvironment.QueueBackgroundWorkItem . 如果您使用的是.NET Framework 4.5.2,则可以通过HostingEnvironment.QueueBackgroundWorkItem获得解决方案。 You can read more about it in Fire and Forget on ASP.NET . 您可以在Fire and Forget on ASP.NET阅读有关它的更多信息。 If not, read Returning Early from ASP.NET Requests for a custom implementation. 如果没有,请阅读Returning Early from ASP.NET Requests中的Returning Early from ASP.NET Requests以获取自定义实现。 Both of these excellent articles are by @StephanCleary 这两篇优秀的文章都来自@StephanCleary

If the tasks are independent (don't depend on data from the other tasks), and can be performed independently, then yes, by all means execute them asynchronously. 如果任务是独立的(不依赖于来自其他任务的数据),并且可以独立执行,那么是的,无论如何都要异步执行它们。 If they're Entity Framework, and it's version 6 then it offers Async methods to call, and you don't have to wrap them in Task.Run. 如果它们是实体框架,并且它是版本6,那么它提供了要调用的异步方法,并且您不必将它们包装在Task.Run中。

Even if the tasks aren't independent, you may still be able to order them in a way to make them more efficient when executed. 即使任务不是独立的,您仍然可以以某种方式对它们进行排序,以使它们在执行时更有效。

Whether or not to use Task.Run, however is an important distinction. 但是,是否使用Task.Run是一个重要的区别。 Task.Run will use a ThreadPool thread, which if it's doing something synchronous will block, and therefore reduce the number of ThreadPool theads available to your application. Task.Run将使用ThreadPool线程,如果它正在执行同步操作将阻塞,因此减少了应用程序可用的ThreadPool theads的数量。 If you have many users, and you are executing many tasks, this could be a problem. 如果您有许多用户,并且您正在执行许多任务,那么这可能是个问题。

Try to find async api's rather than using Task.Run. 尝试找到异步api而不是使用Task.Run。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM