简体   繁体   English

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

[英]Managing DbContext lifetime in ASP.NET Core SignalR

I have implemented an ASP.Core SignalR Application. 我已经实现了ASP.Core SignalR应用程序。

A shared hub class is invoking a signal to all its client on every 10 seconds from class SharedHub (this class is not inherited from Hub it has logic to get IHubContext to invoke) 共享集线器类每隔10秒从类SharedHub向其所有客户端调用一个信号(此类不是从Hub继承的,它具有获取IHubContext以调用的逻辑)

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

Also in the same class once a new connection established a method called to update database 同样在同一个类中,一个新连接建立了一个名为update database的方法

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

Problem with this implementation is if the connection is currently calling Tick() method and also a client connected the same time. 此实现的问题是,如果连接当前正在调用Tick()方法,并且同时连接的客户端也是如此。 _context throws an error saying: _context抛出错误说:

_context in use. _context正在使用中。

(I'll update exact error message once I reproduce). (一旦我重现,我会更新确切的错误消息)。

What I have done ? 我做了什么 ?

I have implemented a factory method to get a new instance of _context on top of every method 我已经实现了一个工厂方法来在每个方法的_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();
}

This actually solved the problem. 这实际上解决了这个问题。 But it seems not the right thing to do. 但这似乎不是正确的做法。 I am not sure of the performance when getting a new context every time on top of every method. 每次在每个方法的基础上获取新的上下文时,我不确定性能。 this seems bad practice. 这似乎是不好的做法。

I want to know what are the possible implementation for this scenario. 我想知道这种情况可能的实现方式。

In the first approach DbContext is shared between operations at the same time and it cause error and unexpected result. 在第一种方法中, DbContext同时在操作之间共享,并导致错误和意外结果。 To avoid create and dispose DbContext every time in the second approach, DbContextPooling can help performance. 为了避免每次在第二种方法中创建和处理DbContextDbContextPooling可以帮助提高性能。

A pool of reusable instances can be created. 可以创建可重用实例池。 Instead of disposing an instance, it returns to the pool and resets the instance to its default state. 它不是处理实例,而是返回池并将实例重置为其默认状态。 So instead of creating a new instance every time, the code will first check if there is an instance available in the pool or not. 因此,代码不是每次都创建一个新实例,而是首先检查池中是否有可用的实例。

You can enable DbContextPooling in Configure method in startup class: 您可以在startup类的Configure方法中启用DbContextPooling

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

The default pool size value is 128. Read this article for more info. 默认池大小值为128.有关详细信息,请阅读本文

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM