Search code examples
c#blazor-webassembly

Blazor Webassembly Clientside Timeout on long operation


I have created a Blazor Webassembly client only application.

There are functions that take awhile to complete - and when they occur, a pop-up window appears stating the page is unresponsive.

I know this particular function will take a long time to complete, and wondered whether there was a way for this particular page to have a longer time out so that the user doesn't have to click the "Wait" button that appears in Chrome?

Some code hidden in a css or app file somewhere?

Or a better way to handle this issue?


Solution

  • Sounds like the entire operation is running synchronously on the browser's application thread.

    If your method takes a long time due to I/O operations (disk access, db access) then leverage the async methods provided by the underlying providers and 'await' those to release the browser's thread.

    If the operation is truly synchronous all the way, then fire that operation on a new thread, using:

    await Task.Run(() => DoLongSyncOperation());
    

    Then, update your UI component in Blazor to show a "Loading" message.

    e.g.

    @if (_theResult == null)
    {
        <div>Loading ...</div>
    }
    else
    {
        <div>@_theResult</div>
    }
    
    <button onclick=@RunJobAsync>Run Job</button>
    
    @code {
        string? _theResult = null;
    
        async Task RunJobAsync()
        {
            _theResult = null;
    
            // Force UI Update to display "Loading ..."
            StateHasChanged();
    
            // If operation is truly sync:
            string result = await Task.Run(() => DoLongSyncOperation());
            // Or, If provider offers an async method:
            string result = await DoLongOperationAsync();
    
            _theResult = result;
        }
    }
    

    The 'await' statement will allow control to be released back to UI and prevent the error message you are getting, whilst showing an indication to the user of either the results or a loading message.

    NOTE: To the best of my knowledge, Blazor WebAssembly actually runs on a single thread, but using scheduling trickery it can release control back to UI and share the single thread's resources across the UI and the running task when that task is 'awaited'.