在ASP.NET Core SignalR中管理DbContext生存期

问题描述 投票:0回答:1

我已经实现了ASP.Core SignalR应用程序。

共享集线器类每隔10秒从类SharedHub向其所有客户端调用一个信号(此类不是从Hub继承的,它具有使IHubContext调用的逻辑)

public void Tick(){
    var time = _context.table.time;
    invoke('tick', time.tick);
}

同样在同一个类中,一个新连接建立了一个名为update database的方法

public void UpdateSocketConnection(int connectionId){
    var connection =_context.connection;
    connection.id = connectionId;
    _context.saveChanges();
}

此实现的问题是,如果连接当前正在调用Tick()方法,并且同时连接的客户端也是如此。 _context抛出错误说:

_context正在使用中。

(一旦我重现,我会更新确切的错误消息)。

我做了什么 ?

我已经实现了一个工厂方法来在每个方法的基础上获得_context的新实例

public void Tick(){
    var time = factory.GetContext().time;
    invoke('tick', time.tick);
}

public void UpdateSocketConnection(int connectionId){
    var context = Factory.getContext();

    var connection =context.connection;
    connection.id = connectionId;
    context .saveChanges();
}

这实际上解决了这个问题。但这似乎不是正确的做法。每次在每个方法的基础上获取新的上下文时,我不确定性能。这似乎是不好的做法。

我想知道这种情况可能的实现方式。

c# asp.net-core signalr
1个回答
0
投票

在第一种方法中,DbContext同时在操作之间共享,并导致错误和意外结果。为避免每次在第二种方法中创建和处置DbContextDbContextPooling可以帮助提高性能。

可以创建可重用实例池。它不是处理实例,而是返回池并将实例重置为其默认状态。因此,代码不是每次都创建一个新实例,而是首先检查池中是否有可用的实例。

您可以在DbContextPooling类中的Configure方法中启用startup

services.AddDbContextPool<YourContext>(options => options.UseSqlServer(connection));

默认池大小值为128.有关详细信息,请阅读this article

© www.soinside.com 2019 - 2024. All rights reserved.