Ger*_*hes 5 signalr entity-framework-core asp.net-core asp.net-core-signalr
我正在尝试实现 SignalR 以便使用来自角度前端应用程序的数据。
我已经检查了谷歌上能找到的所有结果,但仍然无法解决我的问题。
我收到的错误是:
无法访问已释放的上下文实例。导致此错误的一个常见原因是处置从依赖项注入解析的上下文实例,然后尝试在应用程序的其他位置使用相同的上下文实例。如果您在上下文实例上调用“Dispose”或将其包装在 using 语句中,则可能会发生这种情况。如果您使用依赖项注入,则应该让依赖项注入容器负责处理上下文实例。对象名称:“AdminContext”
控制器
[Route("api/[controller]")]
[ApiController]
public class ChartController : ControllerBase
{
private IHubContext<ChartHub> _hub;
private readonly ILiveMonitoringService _service;
public ChartController(IHubContext<ChartHub> hub, ILiveMonitoringService service)
{
_hub = hub;
_service = service;
}
public IActionResult Get()
{
var timerManager = new TimerManager(async () => await _hub.Clients.All.SendAsync("transferchartdata", await _service.GetAllAsync()));
return Ok(new { Message = "Request Completed" });
}
}
Run Code Online (Sandbox Code Playgroud)
服务
public Task<List<LiveMonitoring>> GetAllAsync()
{
return _repository.GetAll().Take(100).ToListAsync();
}
Run Code Online (Sandbox Code Playgroud)
存储库
public IQueryable<TEntity> GetAll()
{
try
{
return _adminContext.Set<TEntity>();
}
catch (Exception ex)
{
throw new Exception("Couldn't retrieve entities");
}
}
Run Code Online (Sandbox Code Playgroud)
可能是什么问题呢?
我很确定这TimerManager是你的问题。您没有显示它的声明,但看起来它的构造函数接受在稍后某个时间点调用的回调。这就是问题所在。您的作用域服务将在回调中捕获,并在请求结束后的_service某个时间点使用。因此,请求结束后,将被释放,并且您将使用已释放的上下文。DbContext_service
解决方法是先获取数据,然后再将其传递到回调中,这样就_service不会被捕获到该回调中,如下所示:
public async Task<IActionResult> Get()\n{\n var liveMonitorings = await _service.GetAllAsync();\n var timerManager = new TimerManager(async () => await _hub.Clients.All.SendAsync("transferchartdata", liveMonitorings));\n return Ok(new { Message = "Request Completed" });\n}\nRun Code Online (Sandbox Code Playgroud)\n我们需要将返回类型更改Get为Task<IActionResult>支持async调用。
如果您实际上想_service.GetAllAsync()稍后Get在回调内调用(而不是在请求时),则需要注入 anIServiceScopeFactory来为该回调内的服务创建一个作用域,如下所示:
public IActionResult Get([FromServices] IServiceScopeFactory serviceScopeFactory)\n{\n var timerManager = new TimerManager(async () => \n {\n using(var scope = serviceScopeFactory.CreateScope()){\n var service = scope.ServiceProvider.GetRequiredService<ILiveMonitoringService>(); \xe2\x80\x8b\n \xe2\x80\x8bvar liveMonitorings = await service.GetAllAsync();\n \xe2\x80\x8breturn await _hub.Clients.All.SendAsync("transferchartdata", liveMonitorings);\n \xe2\x80\x8b }\n \xe2\x80\x8b});\n \xe2\x80\x8breturn Ok(new { Message = "Request Completed" });\n}\nRun Code Online (Sandbox Code Playgroud)\n这样你就不需要将你注入_service到控制器的构造函数中(因为它根本没有被使用)。\n\xe2\x80\x8b
| 归档时间: |
|
| 查看次数: |
3489 次 |
| 最近记录: |