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

Blazor Web应用中仅Players页面导航后DbContext被释放,触发「无法访问已释放对象」错误

Blazor Web应用中仅Players页面导航后DbContext被释放,触发「无法访问已释放对象」错误

这种只在单个页面蹦出来的问题真的挺挠头的,毕竟其他页面都是抄的同样的CRUD逻辑,偏偏就Players页面出状况。我帮你梳理几个最可能的原因和解决方向,你可以挨个排查:

  • 先查PlayersService的生命周期注册
    你先去Program.cs里看看PlayersService是怎么注册的,要是注册成了AddSingleton<PlayersService>()就麻烦了——DbContext默认是Scoped生命周期,Singleton服务会长期持有Scoped的DbContext,等作用域结束(比如导航到新页面)DbContext被释放,Singleton还在引用它,自然就会报错。改成AddScoped<PlayersService>(),让它和DbContext的生命周期保持一致,才是正确的做法。

  • 检查PlayersService里DbContext的使用方式
    要是PlayersService里把DbContext作为类的私有字段存起来,比如构造函数注入后就一直持有,然后在异步方法里延迟使用,那导航后组件所在的Scoped作用域被释放,DbContext也跟着被回收,这时候服务里的异步操作再去访问DbContext就会炸。
    更稳妥的做法是用IDbContextFactory来创建DbContext实例,每次用的时候创建、用完就释放,比如:

    public class PlayersService
    {
        private readonly IDbContextFactory<YourDbContext> _contextFactory;
    
        public PlayersService(IDbContextFactory<YourDbContext> contextFactory)
        {
            _contextFactory = contextFactory;
        }
    
        public async Task<Player> GetPlayerByIdAsync(int id)
        {
            using var context = _contextFactory.CreateDbContext();
            return await context.Players.FindAsync(id);
        }
    }
    

    这样每次方法调用都用独立的DbContext实例,完全不依赖外部作用域,就不会有被提前释放的问题。另外注意别返回延迟执行的IQueryable,要立刻用ToListAsync()把结果拉到内存里,避免后续渲染时DbContext已经没了。

  • 排查页面组件里的未完成异步操作或事件订阅
    看看Players页面里有没有在生命周期方法(比如OnInitializedAsync、OnAfterRenderAsync)里启动了未完成的异步任务,或者订阅了PlayersService的事件但没在组件销毁时取消订阅。比如如果组件里写了service.PlayerUpdated += HandlePlayerUpdated;,但没在DisposeAsync里取消,组件导航销毁后,服务还持有组件引用,可能会导致作用域混乱,连带DbContext被提前释放。

  • 检查Edit按钮的点击逻辑
    会不会是点击Edit按钮时,你先触发了某个异步操作,还没等它完成就立刻导航了?比如类似这样的代码:

    <button @onclick="async () => { await service.SomeAsyncOperation(player.Id); navigationManager.NavigateTo($"/player/{player.Id}"); }">编辑</button>
    

    要是SomeAsyncOperation还在访问DbContext的时候,导航已经触发导致组件和DbContext被释放,那异步操作后续的步骤就会报错。这种情况要确保异步操作完全完成后再导航,或者把操作逻辑移到Edit页面里处理。

另外因为其他页面都是复制粘贴的,你可以对比PlayersService和其他正常服务(比如SeasonsService)的代码实现、注册方式,大概率能快速找到差异点定位问题。

备注:内容来源于stack exchange,提问作者Rafael Osuna Dominguez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 12:35:35