1

I have following code where i fetch results from SQL server. These are razor pages, blazor framework .Net

<button @onclick="Filter">Filter</button>

@{

async Task Filter() {
    await FetchFromDb();
}

This query runs for 18 seconds. So i want to show loading spinner. In blazor, you can use a predefined div with spinner class to do this.

<div class="spinner"> </div>

I want to use this div like following

@(IsLoading) {
<div class="spinner"></div>
} else {

show results from query
}

For which i need to change the Filter function as follows

async Task Filter() {
    IsLoading = true;
    await FetchFromDb();
    IsLoading = false;
}

But I figured, that the whole process of changing IsLoading=true and Isloading=false is done in one go and i don't see a spinner.

Is there a way to change IsLoading=true, while Filter function is getting results from Db in await FetchFromDb(); ?

@(IsLoading) {
<div class="spinner"></div>
} else {

show results from query
}


async Task Filter() {
    IsLoading = true;
    await FetchFromDb();
    IsLoading = false;
}

But this doesn't work. IsLoading doesn't get updated on changing IsLoading=True.

1 Answer 1

8

This looks like:

async Task Filter() {
    IsLoading = true;
    await FetchFromDb();
    IsLoading = false;
}

isn't really an async code block.

You should be able to do this and it works:

async Task Filter() 
{
    IsLoading = true;
    await Task.Delay(1);
    await FetchFromDb();
    IsLoading = false;
}

On the assumption that Filter is being called from a UI event such as a button press this is what happens.

The Task.Delay yields control back to the UI event handler. It (the UI event handler) calls StateHasChanged and yields awaiting Filter. The Renderer gets processor time to service its render queue and runs the component render fragment and render the component

I'm assuming await FetchFromDb(); is a call into a database. Either FetchFromDb wraps a Task around a synchronous database call or you're using a database, such as SQLite, that does the same thing internally with it's exposed async library.

Sign up to request clarification or add additional context in comments.

4 Comments

How about await Task.Yield() ? instaed of Task.Delay, seems more readable ?, curios to see which would be quicker, i hear Task.Yield can cause a memory exception, what do you know ?
@fuzzybear - I used to use Yield, but changed over after some enquiries on the topic with MS (prompted by one of these conversations with Henk and Enet a year or so ago). Stephen is an expert on the topic, and his answer to Ionix is the same as the advice I received.
@HenkHolterman - I'm assuming a UI event is triggering the process. I've added that assumption to the answer as the OP didn't actually say so. For anyone interested this is the ComponentBase UI event hander code - github.com/dotnet/aspnetcore/blob/…
@HenkHolterman - I've clarified It as I can see the reason for confusion. I think I will write a Question/Answer to cover the topic and thus have something to refer to.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.