You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SignalR Hub已释放引发ObjectDisposedException问题求助

解决SignalR中"Cannot access a disposed object. Object name: 'SHHub'"错误

问题原因

这个错误是因为当前的SHHub实例已被SignalR框架释放,但你仍尝试访问它的Clients属性。通常出现在以下场景:

  • Hub方法中存在未正确await的异步操作,导致线程阻塞,SignalR提前回收Hub实例
  • 方法内的耗时操作(如数据库读写)超出SignalR的Hub实例生命周期,导致实例被释放
  • 直接依赖当前Hub实例的Clients属性发消息,而非全局的IHubContext

解决方案

1. 确保所有异步操作正确使用await

检查DBService.GetMultiPlayerById和DBService.SaveMultiPlayer方法,确保它们是原生异步实现,且调用时都添加了await。如果是同步代码包装的异步(比如用Task.Run),可能引发线程上下文问题,建议调整为原生异步数据库操作。

2. 使用IHubContext替代当前Hub实例发送消息

IHubContext是SignalR提供的全局上下文对象,不依赖单个Hub实例的生命周期,是跨场景发送消息的标准方式。

修改步骤:

  • 在SHHub的构造函数中注入IHubContext<SHHub>:
private readonly IHubContext<SHHub> _hubContext;

public SHHub(IHubContext<SHHub> hubContext)
{
    _hubContext = hubContext;
}
  • 将Start方法中最后一行发消息的代码替换为:
await _hubContext.Clients.Group(pMultiPlayerId).SendAsync("StartedGame", $"{oNickName} has started the game");

3. 优化耗时操作

如果数据库操作确实耗时较长,建议将这类操作移到后台服务(比如IHostedService),操作完成后再通过IHubContext发送消息,避免长时间占用Hub实例导致被回收。

为什么Join方法能正常工作?

Join方法内的操作逻辑简单、执行速度快,在Hub实例被释放前就完成了消息发送。而Start方法需要遍历所有玩家并更新状态,加上数据库保存操作,耗时稍长,刚好触发了SignalR的实例回收机制。

内容的提问来源于stack exchange,提问作者user2103317

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 21:22:03