0

我在 .netcore 中托管了服务,它运行几个每秒执行 SQL 查询的函数。在运行应用程序一段时间它崩溃时,我知道它耗尽了所有连接池的问题并且我没有正确处理连接。我知道我需要打开和关闭连接。

dbcontext 未处理的异常:System.InvalidOperationException:超时已过期。在从池中获取连接之前超时时间已过。这可能是因为所有池连接都在使用中并且达到了最大池大小。

我面临的问题是我正在使用DBContext它自动获取并为我打开数据库连接,我不必明确告诉我打开连接,但是我该如何关闭连接?每个Scope

public class DBChangeService : DelegatingHandler, IHostedService
        {
            private Timer _timer;
            public SqlDependencyEx _sqlDependency;
            private readonly IHubContext<SignalServer> _hubcontext;
            private readonly IServiceScopeFactory _scopeFactory;

            public DBChangeService(IHubContext<SignalServer> hubcontext, IServiceScopeFactory scopeFactory)
            {
                _scopeFactory = scopeFactory;
                _hubcontext = hubcontext;
            }

            public Task StartAsync(CancellationToken cancellationToken)
            {
                _timer = new Timer(Heartbeat, null, 0, 1000);
                return Task.CompletedTask;
            }

            public async void Heartbeat(object state)
            {
                await _hubcontext.Clients.All.SendAsync("SBSystemBrodcasting", SBSystemApps());
                await _hubcontext.Clients.All.SendAsync("SBUserBrodcasting", SBNonSystemApps());
            }

            public List<SomeModel> SBSystemApps()
            {
                using (var scope = _scopeFactory.CreateScope())
                {
                    var _DBcontext = scope.ServiceProvider.GetRequiredService<PlatformStatusContexts>();
                    var result = _DBcontext.SomeModels.FromSql((
                                @"SELECT 
                    a.app_guid as AppGuid,
                    a.name as AppName,
                    a.state as AppState,
                    a.created_at as AppCreatedAt,
                    a.updated_at as AppUpdatedAt,
                    a.foundation as AppFoundation,

                    s.name as SpaceName,
                    o.name as OrgName
                FROM
                    apps as a
                INNER JOIN
                    spaces as s ON a.space_guid = s.space_guid
                INNER JOIN
                    organizations as o ON s.org_guid = o.org_guid
                where s.name = 'system' and o.name = 'system' and a.foundation = 2")).ToList();

                    return result;
                }
            }

            public List<SomeModel> SBNonSystemApps()
            {
                using (var scope = _scopeFactory.CreateScope())
                {
                    var _DBcontext = scope.ServiceProvider.GetRequiredService<PlatformStatusContexts>();

                    var result = _DBcontext.SomeModels.FromSql((
                                @"SELECT 
                    a.app_guid as AppGuid,
                    a.name as AppName,
                    a.state as AppState,
                    a.created_at as AppCreatedAt,
                    a.updated_at as AppUpdatedAt,
                    a.foundation as AppFoundation,

                    s.name as SpaceName,
                    o.name as OrgName
                FROM
                    apps as a
                INNER JOIN
                    spaces as s ON a.space_guid = s.space_guid
                INNER JOIN
                    organizations as o ON s.org_guid = o.org_guid
                where s.name != 'system' and o.name != 'system' and a.foundation = 2")).ToList();
                    return result;
                }
            }


            public Task StopAsync(CancellationToken cancellationToken)
            {
                //Timer does not have a stop. 
                _timer?.Change(Timeout.Infinite, 0);
                return Task.CompletedTask;
            }
        }

启动:

services.AddDbContext<PCFStatusContexts>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

连接字符串:

"DefaultConnection": "Server=address,port;Database=dbname;User Id=uname;Password=password;Trusted_Connection=false;MultipleActiveResultSets=true;"

更新:

数据库上下文:

public partial class PlatformStatusContexts : DbContext
{
    public PlatformStatusContexts()
    {
    }

    public PlatformStatusContexts(DbContextOptions<PlatformStatusContexts> options): base(options)
    {
    }

    public virtual DbSet<Apps> Apps { get; set; }
    public virtual DbSet<Organizations> Organizations { get; set; }
    public virtual DbSet<Spaces> Spaces { get; set; }
    public DbQuery<SomeModel> SomeModels { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        //model builder for each table


    }
}
4

1 回答 1

-1

您可以尝试使用与上下文一起使用,如下所示

 using(var _DBcontext = scope.ServiceProvider.GetRequiredService<PlatformStatusContexts>())
 {
      var result = _DBcontext.SomeModels.FromSql((
                                @"SELECT 
                    a.app_guid as AppGuid,
                    a.name as AppName,
                    a.state as AppState,
                    a.created_at as AppCreatedAt,
                    a.updated_at as AppUpdatedAt,
                    a.foundation as AppFoundation,

                    s.name as SpaceName,
                    o.name as OrgName
                FROM
                    apps as a
                INNER JOIN
                    spaces as s ON a.space_guid = s.space_guid
                INNER JOIN
                    organizations as o ON s.org_guid = o.org_guid
                where s.name = 'system' and o.name = 'system' and a.foundation = 2")).ToList();

                    return result;

 }
于 2019-09-04T16:06:40.977 回答