ASP.NET Core: вторая операция началась в этом контексте до завершения предыдущей операции - PullRequest
0 голосов
/ 21 ноября 2018

Я периодически получаю следующую ошибку на одном из моих методов SignalR:

Ошибка: Произошла непредвиденная ошибка при вызове AcceptQueuedUser на сервере.InvalidOperationException: вторая операция началась в этом контексте перед завершением предыдущей операции.Ни один из членов экземпляра не гарантированно является потокобезопасным.

Каждый раз, когда я сталкиваюсь с этой ошибкой, в первую очередь я проверяю, чтобы все мои вызовы async метода были await ed.Тем не менее, я просмотрел всю свою кодовую базу в поисках асинхронных методов, в которых отсутствует ключевое слово await.Я использовал regex, чтобы попытаться отследить его, а также проверку ReSharper «Асинхронный вызов метода без выражения выражения» для всего решения.Никаких костей.

У меня такое чувство, что эта проблема связана с SignalR, поскольку у меня никогда не было таких проблем с обычными конечными точками / контроллерами API.Я впрыскиваю свою область действия DbContext в мой концентратор SignalR, как это делается в любом обычном Controller:

 public class ChatQueueHub<TUser> : Hub<IChatQueueHubClient>
        where TUser : class, IChatRoomUser
    {
        private readonly IChatQueueRepository _chatQueueRepository;
        /// <summary>
        /// Default constructor
        /// </summary>
        public ChatQueueHub(IChatQueueRepository chatQueueRepository)
        {
          _chatQueueRepository = chatQueueRepository
        }

        public async Task<ApiResponse<string>> AcceptQueuedUser(int userQueueId)
        {
            // ...
            await _chatQueueRepository.RemoveQueuedUserAsync(userQueueUser);
            // ...
            return new ApiResponse<string>(newChatroom.Id, BaseApiCode.Success);
        }
    }

Здесь я впрыскиваю IChatQueueRepository, который внедряет DbContext в себя и выполняет всеконтекстные операции.

У меня такое ощущение, что это связано с какой-то странной проблемой с многопоточностью в SignalR, но я не вижу ничего ненормального в моем коде.Насколько я знаю, SignalR создает новый концентратор для каждого RPC, отправляемого по проводной сети.

Какие еще вещи я могу найти, что может вызвать A second operation started on this context before a previous operation completed. Any instance members are not guaranteed to be thread safe., помимо нежелательных асинхронных вызовов?

Редактировать:

Теперь я вижу, что документация по внедрению ASP.NET Core Dependancy гласит следующее:

Контексты Entity Framework должны быть добавлены в контейнер службы с использованием времени существования области,Это обрабатывается автоматически с помощью вызова метода AddDbContext при регистрации контекста базы данных. Службы, использующие контекст базы данных, также должны использовать срок действия области.

Концентраторы SignalR являются временными, поэтому, возможно, это вызывает проблему.Как правильно получить доступ к DBContext из SignalR Hub?

...