Course contentsShow
← C#
Lesson 1387 of 1,90812. Modern Frontend with Razor and BlazorFree lesson

Managing Long-running Tasks

Handle heavy processing without freezing the UI by using background service tasks.

In this lesson, you will learn how to prevent UI freezes in Blazor by offloading heavy computational tasks to background processes.

When a user triggers a method that performs complex calculations or intensive data processing on the main UI thread, the browser stops responding. This creates a "janky" experience where buttons won't click and animations freeze. To keep your Blazor application responsive, you must shift these tasks to the background and notify the UI once they complete.

Asynchronous Offloading

The simplest way to handle this is by leveraging Task.Run combined with a state management approach that lets the UI know when to re-render. Instead of blocking the execution flow, you wrap the logic in a task and use InvokeAsync(StateHasChanged) to update the component after the background work finishes.

Consider this example where we process a large dataset:

private bool _isProcessing;
private string _result = "Waiting...";

private async Task StartHeavyProcess()
{
    _isProcessing = true;
    _result = "Calculating...";

    // Offload to background thread
    await Task.Run(async () =>
    {
        await Task.Delay(5000); // Simulate heavy work
        _result = "Process Complete!";
    });

    _isProcessing = false;
    StateHasChanged(); // Notify Blazor to refresh the UI
}

Keeping the UI Responsive

By using await Task.Run(...), you hand off the heavy lifting to the ThreadPool. Because the method is awaited, the UI thread is freed up immediately after the task starts, allowing the browser to remain fluid. Once the task finishes, the execution returns to the component, and calling StateHasChanged() ensures that the updated _result is rendered on the screen.

If the task is extremely long-running, it is best practice to implement a progress reporting mechanism or a cancellation token to ensure the user retains control if they navigate away or decide to cancel the operation. Always remember: if your logic takes more than a few milliseconds, it belongs in a background task to protect your user's experience.

Key Takeaway: Offload long-running logic to Task.Run and use StateHasChanged() to bridge the gap between background processing and UI updates to ensure your Blazor application remains responsive.