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

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


一个共享集线器类每 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();

}

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


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


红颜莎娜
浏览 83回答 1
1回答

守着星空守着你

在第一种方法DbContext中,同时在操作之间共享它会导致错误和意外结果。避免DbContext在第二种方法中每次都创建和处理,DbContextPooling可以帮助提高性能。可以创建可重用实例池。它不会处理实例,而是返回池并将实例重置为其默认状态。因此,代码不会每次都创建一个新实例,而是首先检查池中是否有可用实例。您可以在类DbContextPooling中的Configure方法中启用startup:services.AddDbContextPool<YourContext>(options&nbsp;=>&nbsp;options.UseSqlServer(connection));默认池大小值为 128。阅读本文了解更多信息。
打开App,查看更多内容
随时随地看视频慕课网APP