Home > Software design >  Blazor Webassembly Clientside Timeout on long operation
Blazor Webassembly Clientside Timeout on long operation

Time:05-27

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?

CodePudding user response:

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'.

CodePudding user response:

Neil provided the backbone and to add to that, I took the information within this answer:

How to get UI to update

I split my LRQ into three parts and then created a method "RunJobAsync" as suggested, and then within that function that calls each part of the LRQ I added:

StateHasChanged();    
await Task.Delay(1);

After each call, where there is a message passed to the UI.

This seems to give the UI a chance to update and provide a message so that the user at least knows something is happening.

Thanks,

  • Related