- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我编写了一个 aspnet core 控制台应用程序,该应用程序将 Entity Framework Core 与 SQL Server 结合使用。该应用程序有多个 Azure 服务总线队列客户端,我假设每个客户端都在自己的线程中运行消息接收器处理程序 - 因此我相信它是第三方服务总线库中的线程应用程序。
为了避免在每个服务总线队列客户端中配置和创建 SQL 连接,我将依赖项注入(inject)与 Microsoft.Extensions.DependencyInjection.ServiceCollection
结合使用。然后,我将生成的 ServiceProvider
传递到每个服务总线队列客户端。
我的问题是,随着时间的推移,我的程序将停止工作,因为 SQL 连接池耗尽了可用连接。这就像内存泄漏,但它是 SQL 连接泄漏,因为我认为连接永远不会释放回池中。
我对此进行了一些阅读,据我了解,当连接超出范围时,它应该返回到池中。我还了解到线程可能会导致这些问题,这就是我提出服务总线队列客户端的原因,并且我相信消息处理程序是在线程内运行的。
我确信这是我忽略的简单问题,但在尝试了几种不同的方法后我无法修复它。我将在下面粘贴我的代码,然后解释我尝试过的一些事情。
因此,这是配置和创建 ServiceProvider
的代码...
private ServiceProvider BuildServiceProvider()
{
var services = new ServiceCollection();
services.AddDbContext<WibWorkspaceContext>(ConfigureDbContext, ServiceLifetime.Transient);
return services.BuildServiceProvider();
}
然后这是上面代码使用的 ConfigureDbContext
方法...
private void ConfigureDbContext(DbContextOptionsBuilder options)
{
var migrationsAssembly = typeof(WibWorkspaceContext).GetTypeInfo().Assembly.GetName().Name;
var sqlConnectionString = ConfigurationManager.ConnectionStrings["Sql"];
options
.UseLazyLoadingProxies()
.UseSqlServer(sqlConnectionString.ConnectionString, x => x.MigrationsAssembly(migrationsAssembly));
}
然后,我将该 ServiceProvider
传递到每个服务总线消息处理程序中,并在其中调用 GetRequiredService
。因此,我确实相信对 GetRequiredService
的调用发生在服务总线客户端创建的线程内。下面是一些代码片段...
private async Task ProcessMessagesAsync(Message message, CancellationToken token)
{
var sql = m_services.GetRequiredService<WibWorkspaceContext>();
...
}
在ProcessMessagesAsync
中,我使用了DbContext
,但我从不做任何与处置它或任何事情相关的事情。我只是允许它超出范围,仅此而已。
这就是我的代码。该程序将正常运行,直到它开始耗尽 SQL 连接。此时它开始抛出以下错误和堆栈跟踪......
2020-10-02 23:07:55.1660 ERROR Timeout expired. The timeout periodelapsed prior to obtaining a connection from the pool. This may haveoccurred because all pooled connections were in use and max pool sizewas reached.
2020-10-02 23:07:15.3764 ERROR System.InvalidOperationException: 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.
at Microsoft.Data.Common.ADP.ExceptionWithStackTrace(Exception e)
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnectionAsync(Boolean errorsExpected, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnectionAsync(Boolean errorsExpected, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenAsync(CancellationToken cancellationToken, Boolean errorsExpected)
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.AsyncEnumerator.InitializeReaderAsync(DbContext _, Boolean result, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleOrDefaultAsync[TSource](IAsyncEnumerable`1 asyncEnumerable, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleOrDefaultAsync[TSource](IAsyncEnumerable`1 asyncEnumerable, CancellationToken cancellationToken)
at WhatInBoxWorkerService.Queues.CreateRelativityPackageQueueClient.ProcessMessagesAsync(Message message, CancellationToken token) in C:\Users\rcole\Projects\WhatInBox\src\Applications\WhatInBoxWorkerService\Queues\CreateRelativityPackageQueueClient.cs:line 203
at Microsoft.Azure.ServiceBus.MessageReceivePump.MessageDispatchTask(Message message)
正如您所料,程序开始崩溃,因为无法从连接池中检索到任何连接。
我尝试过的一件事是使用 AddDbContextPool
而不是 AddDbContext
。
我是否忘记做任何事情?
最佳答案
我怀疑您的依赖项注入(inject)设置存在问题,如下所示:
var sql = m_services.GetRequiredService<WibWorkspaceContext>();
如果m_services
是您从未处置并基于您的评论的根容器
Within ProcessMessagesAsync I make use of the DbContext but I never do anything relating to disposing it or anything. I just allow it to go out of scope and that's it.
那么您最终可能会遇到所有 WibWorkspaceContext
永远不会被释放的情况。
为什么?
我假设您使用 Microsoft 扩展 DI。 transient /作用域服务仅在其作用域结束时才会被释放。如果您从根容器解析它们,则在容器被处置之前它们不会被处置。这就是为什么resolving transient IDisposable
from root container isn't recommended .
要解决此问题,您可能需要自定义范围:
using(var scope = m_services.CreateScope())
{
var sql = scope.ServiceProvider.GetRequiredService<WibWorkspaceContext>();
} // <--- Your DB context will be disposed here
关于c# - 在 ServiceProvider 中使用时,如何防止 DbContext 用完可用的池连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64180433/
在 .NET Core Console 应用程序中,我想使用内置的依赖注入(inject),包括自动处理链中的 IDisposable 对象。在 ASP.NET Core 中,对象是随每个请求创建和释
我有一个关于 Laravel 的问题。使用ServiceProviders的区别在哪里?或 Middleware在 Laravel 中? 所以我的意思是,我什么时候使用 ServiceProvider
我创建了这个提供程序: php artisan make:provider ShortcodesServiceProvider 然后我不得不删除该文件,但现在我得到了 FatalThrowableEr
我正在权衡在独立包中测试我的 ServiceProvider 的利弊。 由于 laravel 应用程序不是包的依赖项,我认为我不应该/不能编写集成测试。 但有时我在使用语句中出现拼写错误,导致我只为这
我正在使用这种方法构建服务实现: 我正在使用 Microsoft.Extensions.DependencyInjection 并尝试实现以下目标: 创建本地 ServiceCollection 并保
文件:Composer.json --------------------------------------- { "name": "laravel/laravel",
我有asp.net 核心应用程序。我将 Options 存储在 appsettings.json 文件中。我向服务注册了 Options,然后尝试在 Configure 方法中解决它。 但是服务提供商
设置:在我们公司,我尝试将基于 Ant 的 Netbeans 应用程序迁移到 Maven。我有一个基于 Maven 的 Netbeans 平台应用程序和两个包含 Netbeans 模块的 Maven
我觉得我已经搜索了整个互联网,但似乎无法弄清楚这个问题。我正在使用 Silex(最新版本),似乎无法弄清楚如何使用 Silex 的 ServiceProvider 系统返回一个类的实例以供使用。 我确
所以我有一个 Laravel 服务提供者,我想在应用它时创建一个 DEBUG 日志条目: app['log']->debug('message'); //fails too } } 如何做到这
如果您编写自己的 MarkupExtension,您可能会偶然发现 IServiceProvider serviceProvider 参数在设计时与运行时不同。例如,您无法获取 IRootObject
我为 paypal 创建了一个自定义服务提供商。当我尝试从提供者内部访问配置时,它返回 null。 下面是我写的代码。 public function register() { $this->
我正在用 Laravel 编写一个小 API,部分目的是为了学习这个框架。我想我在文档中发现了一个漏洞,但这可能是因为我不理解“Laravel 方式”来做我想做的事。 我正在编写一个 HTTP API
我正在研究 Laravel 5.2 中的 api 部分,并尝试从 Strava 获取详细信息。正如此链接中提到的 http://socialiteproviders.github.io/provide
我是 PHP 和 Laravel 的新手。我按照本教程将 reCAPTCHA 支持添加到我的 Laravel 应用程序中的页面: http://tutsnare.com/how-to-use-capt
我在 .NET 4.6.2 上有一个 Windows 服务,我在其中使用 .NET ServiceProvider(System.IServiceProvider 接口(interface))将 EF
我想改变路由的路径,但它仍然给出错误 Class HomeController does not exist 下面是我的代码 In app/Http/routes.php page Route::ge
有什么好办法可以拿到ServiceProvider在 AddOpenIdConnect , 或 稍后在我们完全设置 DI 容器的地方配置 ClientSecret? (例如在 Configure(IA
我编写了一个 aspnet core 控制台应用程序,该应用程序将 Entity Framework Core 与 SQL Server 结合使用。该应用程序有多个 Azure 服务总线队列客户端,我
friend 们大家好,我是 Laravel 框架的新手。 我在应用程序文件夹中创建模块目录。 然后我还在模块目录中创建 ServiceProvider.php 文件。 我的文件结构如下。 app\m
我是一名优秀的程序员,十分优秀!