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



我已经实现了一个ASP。核心信号R应用程序。

共享中心类每 10 秒向其所有客户端调用一次信号 从类SharedHub(这个类不是从Hub继承的,但它有逻辑来调用IHubContext)

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

同样在同一类中,一旦新连接建立了称为更新数据库的方法

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();
}

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

我想知道这种情况的可能实现是什么。

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

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

您可以在类startupConfigure方法中启用DbContextPooling

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

默认池大小值为 128。有关详细信息,请阅读本文。

最新更新