无法访问已处置的上下文实例。导致此错误的一个常见原因是处置从依赖项注入解析的上下文实例

问题描述 投票:0回答:1

添加

_timer
字段后,出现此错误。在添加
_timer
字段之前,它按预期工作。这是 signalR hub 类代码。

System.ObjectDisposeException:'无法访问已处置的上下文 实例。导致此错误的一个常见原因是处置上下文实例 这是通过依赖注入解决的,然后尝试 在应用程序的其他地方使用相同的上下文实例。这可能 如果您在上下文实例上调用“Dispose”,则会发生这种情况,或者 将其包装在 using 语句中。如果您正在使用依赖项 注入,你应该让依赖注入容器来处理 处理上下文实例。对象名称:'xxContext'。

public class ProgressHub : Hub
{
    private readonly MyContext _dbContext;
    private readonly Timer _timer;

    public ProgressHub(MyContext dbContext)
    {
        _dbContext = dbContext;

        _timer = new Timer(async state => await SendProgressUpdate(), null, TimeSpan.Zero, TimeSpan.FromSeconds(30));
    }

    public async Task SendProgressUpdate()
    {         
        var totalCompleted = _dbContext.xxx;
        
        // code removed for brevity
    }
}

尝试实现Dispose方法,但仍然无济于事。

public class ProgressHub : Hub
{
    private readonly MyContext _dbContext;
    private Timer _timer;
    private bool _timerDisposed = false;


    public ProgressHub(MyContext dbContext)
    {
        _dbContext = dbContext;

        _timer = new Timer(async state => await SendProgressUpdate(), null, TimeSpan.Zero, TimeSpan.FromSeconds(30));
    }

    public async Task SendProgressUpdate()
    {
        if (_timerDisposed)
        {
            return;
        }

        // Error happens here.
        var totalCompleted = _dbContext.xxx;
    }

    public void Dispose()
    {
        _timer?.Change(Timeout.Infinite, Timeout.Infinite);
        _timer?.Dispose();
        _timerDisposed = true;
    }
}
c# signalr
1个回答
0
投票

请使用

IServiceProvider
,而不是直接将DbContext注入到您的hub中。它可以帮助您解决问题。

public class ProgressHub : Hub
{
    private readonly IServiceProvider _serviceProvider;
    private readonly Timer _timer;

    public ProgressHub(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;

        _timer = new Timer(async state => await SendProgressUpdate(), null, TimeSpan.Zero, TimeSpan.FromSeconds(30));
    }

    public async Task SendProgressUpdate()
    { 
        using (var scope = _serviceProvider.CreateScope())
        {
            var dbContext = scope.ServiceProvider.GetRequiredService<MyContext>();
            
            var totalCompleted = dbContext.xxx;
            
            // code removed for brevity
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.