Skip to content

fix: Semphore slim disposed object access error in EntityFrameworkAdapter and FluentDataGrid #2769

@yrova

Description

@yrova

🐛 Bug Report

Encountered this issue when using the recent FluentDataGrid changes in version v4.10.1 with entity framework. Noticed that if a query is long running, if you attempt to navigate away from the page fast enough, it will produce an error. Seems the entity framework adapter is still trying to access the semaphore slim after it's been disposed.

💻 Repro or Code Sample

  1. Create a Blazor project with a nav menu and a page utilizing FluentDataGrid and EFcore.
  2. Ensure the ef core page is using a FluentPaginator.
  3. Ensure the data being loaded is a long running query to be able to reproduce this issue more reliably.
  4. Quickly Navigate between pages using the Nav menu
  5. Page should error with "An unhandled error has occurred"

Example of EFCore Page (Code sample reduced/changed to just the relevant information):

@attribute [Route(AppRoutes.Customers)]
@using Microsoft.EntityFrameworkCore
@inject ILogger<CustomersPage> Logger
@inject IDbContextFactory<CustomerContext> DbContextFactory

<FluentDataGrid
    TGridItem="Customers"
    Items="@Customers"
    Pagination="@_pagination"
    ShowHover="true"
    ResizableColumns="true">
    <PropertyColumn Property="@(m => m.Name)" Title="Name" Sortable="true"/>
</FluentDataGrid>
<FluentPaginator State="@_pagination"/>

@code {
    private readonly PaginationState _pagination = new() { ItemsPerPage = 20 };
    private IQueryable<Customer>? Customers { get; set; }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            await LoadCustomersAsync();
        }
    }

    private async Task LoadCustomersAsync()
    {
        try
        {
            var context = await DbContextFactory.CreateDbContextAsync();
            var query = context.Customers
                .Where(m => _showInactive ? !m.Active : m.Active);

            query = query.OrderByDescending(m => m.AddedDatetime);
            Customers = query;
        }
        catch (Exception ex)
        {
            Logger.LogError(ex, "Error loading customers.");
        }
    }
}

🤔 Expected Behavior

Expect the entity framework adapter to gracefully handle the disposal of components.

😯 Current Behavior

fail: Microsoft.AspNetCore.Components.Server.Circuits.CircuitHost[111]
      Unhandled exception in circuit 'FuIWJTG5u0CUs9wfYSum8tjyGGatatSKk8s6__-2NH8'.
      System.ObjectDisposedException: Cannot access a disposed object.
      Object name: 'System.Threading.SemaphoreSlim'.
         at System.Threading.SemaphoreSlim.Release(Int32 releaseCount)
         at Microsoft.FluentUI.AspNetCore.Components.DataGrid.EntityFrameworkAdapter.EntityFrameworkAsyncQueryExecutor.ExecuteAsync[TResult](Func`1 operation) in /_/src/Extensions/DataGrid.EntityFrameworkAdapter/EntityFrameworkAsyncQueryExecutor.cs:line 30
         at Microsoft.FluentUI.AspNetCore.Components.FluentDataGrid`1.ResolveItemsRequestAsync(GridItemsProviderRequest`1 request) in /_/src/Core/Components/DataGrid/FluentDataGrid.razor.cs:line 723
         at Microsoft.FluentUI.AspNetCore.Components.FluentDataGrid`1.RefreshDataCoreAsync() in /_/src/Core/Components/DataGrid/FluentDataGrid.razor.cs:line 632
         at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
         at Microsoft.FluentUI.AspNetCore.Components.Infrastructure.EventCallbackSubscribable`1.InvokeCallbacksAsync(T eventArg) in /_/src/Core/Infrastructure/EventCallbackSubscribable.cs:line 22
         at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)

🌍 Your Environment

  • OS & Device: Windows 11 PC
  • Browser: Microsoft Edge
  • .NET and Fluent UI Blazor library Version 8.0.2 and 4.4.1
  • Blazor Hosting Model: Blazor Server (Server Side)
  • EF Core Version: 8.0.8
  • Database Used: Microsoft SQL Azure (RTM) - 12.0.2000.8

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions