Display wait or spinner on API call

Option 1: Using Task.Delay(1)

  • Use an async method.
  • Use await Task.Delay(1) or await Task.Yield(); to flush changes
private async Task AsyncLongFunc()    // this is an async task
{
    spinning=true;
    await Task.Delay(1);      // flushing changes. The trick!!
    LongFunc();               // non-async code
    currentCount++;
    spinning=false;
    await Task.Delay(1);      // changes are flushed again    
}

Option 1 is a simple solution that runs ok but looks like a trick.

Option 2: Using Task.Run() (not for WebAssembly)

On January’2020. @Ed Charbeneau published BlazorPro.Spinkit project enclosing long processes into task to don’t block the thread:

Ensure your LongOperation() is a Task, if it is not, enclose it into a Task and await for it:

async Task AsyncLongOperation()    // this is an async task
{
    spinning=true;
    await Task.Run(()=> LongOperation());  //<--here!
    currentCount++;
    spinning=false;
}

Effect

a spinner loading data

Spinner and server side prerendering

Because Blazor Server apps use pre-rendering the spinner will not appear, to show the spinner the long operation must be done in OnAfterRender.

Use OnAfterRenderAsync over OnInitializeAsync to avoid a delayed server-side rendering

    // Don't do this
    //protected override async Task OnInitializedAsync()
    //{
    //    await LongOperation();
    //}

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {            
            await Task.Run(()=> LongOperation());//<--or Task.Delay(0) without Task.Run
            StateHasChanged();
        }
    }

More samples

Learn more about how to write nice spinner you can learn from open source project BlazorPro.Spinkit, it contains clever samples.

More Info

Leave a Comment