【问题标题】:Blazor Server - DbContext is disposed after refreshing pageBlazor Server - 刷新页面后释放 DbContext
【发布时间】:2020-07-21 09:20:15
【问题描述】:

我正在开发一个 Blazor 服务器应用程序,其中所有客户端都将有一个 things 列表,这些客户端中的任何一个都可以更新 thing,这应该会触发一个回调,告诉所有客户端调用 DbContext.Entry(thing).Reload() 所以他们'重新更新。这一切都很好,直到我刷新页面,然后我收到Cannot access a disposed object 错误,我不知道如何解决它。

我有以下服务:

services.AddDbContextPool<MainDbContext>(...);
services.AddSingleton<RefreshService>();

刷新服务.cs:

public class RefreshService {
    public Func<long, Task> OnRefreshThing { get; set; }

    public void RefreshThing(long thingId) => OnRefreshThing?.Invoke(thingId);
}

索引.blazor:

protected override void OnInitialized() {
    RefreshService.OnRefreshIssue += OnRefreshIssue;
}
private async Task OnRefreshThing(long thingId) {
    // This works perfectly until I refresh the page & try to call it again
    Thing thing = await MainDbContext.Things.FindAsync(thingId); // exception is thrown here

    await MainDbContext.Entry(thing).ReloadAsync();
}

下面是触发错误的示例:

Thing thing = Things.Where(t => t.ThingId == 1);
thing.Name = "New name";
RefreshService.RefreshThing(thing.ThingId);

【问题讨论】:

  • Web 应用程序应该是无状态的。您正在尝试将单例服务器端用于可以保留状态的 Web 应用程序,这不是一个好的设计决策。 DbContext 实例应该与传入的请求相关联,或者与另一个在请求内具有范围的实例的生命周期相关联,或者更短的生命周期。不要使用单例对应用程序状态做任何事情,除非该状态是静态的(例如访问 web.config 设置)。
  • 谢谢。我听从了你的建议,一切顺利!

标签: entity-framework asp.net-core entity-framework-core blazor blazor-server-side


【解决方案1】:
  1. 您可以将 RefreshService 修改为 Scoped 而不是 Singleton
  2. AddDbContextPool 没有完全释放 dbcontext 的实例,它会将实例重置为其默认状态,可能是因为重置,它无法再次访问它

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-13
    • 2021-04-05
    • 1970-01-01
    • 2023-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多