#c# #asp.net-core #signalr
#c# #asp.net-core #signalr
Вопрос:
Я внедрил 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();
}
Это фактически решило проблему. Но это кажется неправильным. Я не уверен в производительности при получении нового контекста каждый раз поверх каждого метода. это кажется плохой практикой.
Я хочу знать, какова возможная реализация для этого сценария.
Комментарии:
1. не могли бы вы показать объявление хаба и инициализацию
_context
?
Ответ №1:
В первом подходе DbContext
разделяется между операциями одновременно, и это приводит к ошибке и неожиданному результату. Чтобы избежать создания и удаления DbContext
каждый раз во втором подходе, DbContextPooling
это может повысить производительность.
Может быть создан пул повторно используемых экземпляров. Вместо удаления экземпляра он возвращается в пул и сбрасывает экземпляр в состояние по умолчанию. Таким образом, вместо того, чтобы каждый раз создавать новый экземпляр, код сначала проверяет, есть ли экземпляр, доступный в пуле, или нет.
Вы можете включить метод DbContextPooling
in Configure
в startup
классе:
services.AddDbContextPool<YourContext>(options => options.UseSqlServer(connection));
Значение размера пула по умолчанию равно 128. Прочтите эту статью для получения дополнительной информации.