我已经实现了一个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
同时在操作之间共享,它会导致错误和意外结果。为了避免在第二种方法中每次创建和释放DbContext
,DbContextPooling
可以帮助提高性能。
可以创建可重用实例池。它不会释放实例,而是返回到池并将实例重置为其默认状态。因此,代码将首先检查池中是否有可用的实例,而不是每次都创建一个新实例。
您可以在类startup
Configure
方法中启用DbContextPooling
:
services.AddDbContextPool<YourContext>(options => options.UseSqlServer(connection));
默认池大小值为 128。有关详细信息,请阅读本文。