我的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的正确方法是什么?