use*_*202 5 entity-framework entity-framework-core .net-core asp.net-core ef-core-3.0
我和我的团队在高利用率的 .NET Core Web 应用程序上遇到了一些 EF Core/SQL 池问题。
Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
当 EF Core/ApplicationDbContext 在托管服务 (QueuedHostedService) 上的后台任务中被引用时,问题开始发生。遵循以下指南:
我遵循了推荐的依赖注入和托管服务指南。
相关线路:
启动文件
...
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
...
services.AddScoped<IScopedWorker, ScopedWorker>();
services.AddSingleton<MySingletonThatAddsToBackground>();
// Follow the host service guide from microsoft.
services.AddHostedService<QueuedHostedService>();
services.AddSingleton<IBackgroundTaskQueue, BackgroundTaskQueue>();
Run Code Online (Sandbox Code Playgroud)
MySingletonThatAddsToBackground.cs
public class MySingletonThatAddsToBackground
{
private readonly IBackgroundTaskQueue _taskQueue;
private readonly ILogger _logger;
private readonly CancellationToken _cancellationToken;
public IServiceProvider _services { get; }
public MySingletonThatAddsToBackground(IServiceProvider services, IBackgroundTaskQueue taskQueue,
ILogger<MonitorLoop> logger,
IHostApplicationLifetime applicationLifetime)
{
_services = services;
_taskQueue = taskQueue;
_logger = logger;
_cancellationToken = applicationLifetime.ApplicationStopping;
}
public void DoWorkBackground()
{
// Enqueue a background work item
_taskQueue.QueueBackgroundWorkItem(async token =>
{
try
{
using (var scope = _services.CreateScope())
{
var scopedWorker = scope.ServiceProvider.GetRequiredService<IScopedWorker>();
await scopedWorker.DoWork();
}
}
catch (OperationCanceledException)
{
// Prevent throwing if the Delay is cancelled
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
ScopedWorker.cs
public class ScopedWorker : IScopedWorker
{
private readonly ApplicationDbContext _db;
public ScopedWorker(ApplicationDbContext db)
{
_db = db;
}
public void DoWork()
{
var customers = _db.MyCustomers.ToListAsync();
// Do stuff to customers.
await _db.SaveChangesAsync();
}
}
Run Code Online (Sandbox Code Playgroud)
在MySingletonThatAddsToBackground里面,using (var scope)完成之后,是不是应该disposeScopedWorker作用域,然后disposes (scoped),然后disposes ApplicationDbConext(scoped),然后关闭连接/池连接?
是否有什么我没有正确实施导致连接池泄漏?
EF Core 版本:3.1.4 数据库提供程序:Microsoft.EntityFrameworkCore.SqlServer 目标框架:.NET Core 3.1.4 操作系统:Windows Server 2016、SQL Server 2016 IDE:16.6