实体框架异步方法会消耗ThreadPool线程吗? [英] Do Entity Framework async methods consume ThreadPool threads?

查看:123
本文介绍了实体框架异步方法会消耗ThreadPool线程吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我通常在Web应用程序中使用许多EF Core异步方法,如下所示:

I usually use many EF Core async methods in my web application like this:

await db.Parents.FirstOrDefaultAsync(p => p.Id == id);

我们知道,默认情况下,ThreadPool中的初始线程数仅限于CPU逻辑核的数量.用户请求也由ThreadPool中的线程处理.

As we know, initial number of threads in ThreadPool by default is limited to number of CPU logical cores. Also user requests are handled by threads in ThreadPool.

由于我的应用程序中有许多异步调用,我是否应该担心处理用户请求或性能问题?

Should I worry about handling user requests or performance issues due to many async calls in my application?

推荐答案

由于我的应用程序中有许多异步调用,我是否应该担心处理用户请求或性能问题?

Should I worry about handling user requests or performance issues due to many async calls in my application?

EF Core为存储库提供了一个异步查询接口.无论是异步方式,还是certian方法是否阻塞线程池线程都取决于EF提供程序. SQLServer的SqlClient具有不阻塞线程的基于任务的Async方法.大多数其他提供者也这样做.但是,例如对于EF内存提供程序或SQLite提供程序,它可能是异步同步的,要么同步完成并返回已完成的Task,要么阻塞线程池线程.

EF Core provides an Async query interface for repositories. Whether it's async-all-the-way, or whether certian methods block thread pool threads is dependent on the EF provider. SQLServer's SqlClient has task-based Async methods that don't block threads. Most other providers do too. But for instance for the EF in-memory provider, or perhaps the SQLite provider it may be async-over-sync, either completing synchronously and returning a completed Task, or blocking a thread pool thread.

因此EF通常不会阻塞您的线程.而且,当您对数据库进行异步调用时,它会释放应用程序的线程来执行更多工作.喜欢处理其他请求.如果对数据库的并发请求太多,则每个请求将开始花费更多时间.

So EF normally won't block your threads. And when you make an Async call to the database it frees your application's thread to do more work. Like handle additional requests. If you have too many concurrent requests to your database, each request will start to take more time.

发生这种情况时,您需要一种机制来减慢对数据库的新请求的速度,否则您将陷入困境.数据库服务器所在的EG有2000个正在运行的请求,其中大多数代表已放弃并超时的客户端.而且由于所有旧请求,新请求也没有得到及时处理.

When this happens you need to have a mechanism to slow down the rate of new requests to the database, otherwise you you'll get into a bad state. EG where the database server is has 2000 running requests, most of which are on behalf of clients who've given up and timed out. And new requests aren't handled in a timely manner because of all the old requests.

通常,当您将并发添加到某个点时,吞吐量会增加,但超过该点时,总体吞吐量会下降,有时会急剧下降.像这样:

Generally throughput increases as you add concurrency up to a point, but beyond that point overall throughput decreases, sometimes drastically. Something like this:

由您决定限制整体并发,以防止吞吐量严重下降.最好是尽早使某些请求失败(例如,使用HTTP 503),而不是全部接受并且不完成您的SLA中的任何请求.

It’s up to you to limit overall concurrency to prevent severe degradation in throughput. It’s better to fail some requests early (eg with an HTTP 503) than accept them all and not complete any within your SLA.

使用同步数据库访问的好处之一是,在数据库交互期间,它占用了一个应用程序线程,从而自动向请求流添加了反压力.当所有线程池线程都处于繁忙状态时,有一个请求必须等待线程池线程实际上是一件好事.当您执行所有异步操作后,该控件就会消失,您需要考虑更换它.

One of the benefits of using synchronous database access is that it occupies an application thread for the duration of the database interaction, automatically adding backpressure to the request flow. Having a request have to wait for a thread pool thread when all of the thread pool threads are busy is actually a good thing. When you go all async this control goes away and you need to think about replacing it.

ASP.NET Core当前没有内置限制.您的Web服务器主机可能有一些限制,例如SqlConnection的连接池限制用于限制每个应用程序实例的并发请求数.但是您必须具有某事,它可以让您以有序的方式处理请求量的激增.

ASP.NET Core currently has no built-in throttling. Your web server host may have some, and, for instance, SqlConnection's connection pool limit serves to limit the number of concurrent requests per application instance. But you've got to have something that allows you to handle a surge in request volume in an orderly fashion.

这篇关于实体框架异步方法会消耗ThreadPool线程吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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