Michael
Michael

Reputation: 191

UI Thread blocked when calling an async method (Blazor WASM PWA)

Can anyone help me to understand why the following code is blocking the UI thread...

I've modified the sample application from https://github.com/TrevorDArcyEvans/BlazorSQLiteWasm in order to test the performance of the SQLite database inside a Blazor WebAssembly Progressive Web Application

On a .razor file I have the following

<button onclick="@(async () => CreateMany())" class="btn btn-default btn-sm">
   Insert Many
</button>

Which references:

private async void CreateMany()
{
    var cars = new List<Car>();

    for (int i = 0; i < 1000; i++)
    {             
        cars.Add(new() { Brand = "BMW", Price = 500 });
    }

    var db = await _dbContextFactory.CreateDbContextAsync();
    await db.Cars.AddRangeAsync(cars);

    await db.SaveChangesAsync();

    _cars.Clear();
    _cars.AddRange(db.Cars);
    StateHasChanged();
}

When I click the "Insert Many" button it seems to ignore the fact the it's an async void, and it blocks the UI anyway. Am I missing something here?

.NET 6.0

Upvotes: 1

Views: 1925

Answers (1)

Henk Holterman
Henk Holterman

Reputation: 273244

onclick="@(async () => CreateMany())"

This will give you a "... is not awaited" Warning after a Build. Just use onclick="CreateMany"

Am I missing something here?

It would have been better to use async Task CreateMany() ... but that is not essential.

The main problem is that Sqlite is totally synchronous. await db.SaveChangesAsync(); is a lie, it is not async at all.

So your code would probably work as expected with a different database, but there is not much on offer in Wasm.

Task.Run() is also not effective, so alas, you're stuck with this.

Upvotes: 2

Related Questions