ASP.NET Core:在之前的操作完成之前,第二次在此上下文上开始操作

时间:2018-11-21 16:52:13

标签: c# entity-framework asynchronous signalr

我的SignalR方法之一间歇性地收到以下错误:

  

错误:在计算机上调用“ AcceptQueuedUser”时发生意外错误   服务器。 InvalidOperationException:对此进行了第二次操作   上一个操作完成之前的上下文。任何实例成员   不能保证是线程安全的。

每当我遇到此错误时,我要检查的第一件事就是确保对我的所有async方法调用进行await处理。但是,我遍历了整个代码库,以寻找缺少await关键字的异步方法。我已经使用正则表达式来尝试对其进行跟踪,以及整个解决方案中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实例化一个新的Hub。

除了未等待的异步调用外,我还能寻找什么导致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 Dependency注入文档指出以下内容:

  

实体框架上下文应添加到服务中   容器使用范围内的生存期。这是自动处理的   注册数据库时调用AddDbContext方法   上下文。 使用数据库上下文的服务也应使用   范围内的生存期。

SignalR集线器是瞬态的,所以这可能是导致问题的原因。从SignalR集线器访问DBContext的正确方法是什么?

0 个答案:

没有答案