Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Blazor and ContinueWith on page load

I am new to Blazor. I'm working on a Server App (not WASM).

On a page load, I am loading 2 things to a page. Item1 is loaded at the same time as Item2 via API calls. I'd like individual items to show up as soon as they are available. I was thinking something like

protected override async Task OnInitializedAsync()
{
    var t1 = _service.GetItem1().ContinueWith(t => {
        Item1Loaded = true;
        Item2State = t.Result;
        await InvokeAsync(StateHasChanged);
    });

    var t2 = _service.GetItem2().ContinueWith(t => {
        Item2Loaded = true;
        Item2State = t.Result;
        await InvokeAsync(StateHasChanged);
    });
}

I have a couple questions about this though:

  1. Do I need to worry about canceling these lines if the user navigates away from the component? (would changing a state variable after the component is removed cause a problem) or does Blazor handle that at the framework level somehow?
  2. Do I need to ensure this gets back to a certain thread with a Synchronization Context? It seems like InvokeAsync just does this for me but want to be sure.
  3. Its hard to find lots of modern examples of ContinueWith. async/await is dominant, but I don't think it allows continuations to execute in the order they complete. Is this a reasonable use of it?
like image 451
Ben Zuill-Smith Avatar asked Nov 04 '25 22:11

Ben Zuill-Smith


1 Answers

Since you are using Server side you can do this more cleanly (ContinueWith is more or less obsolete since async / await):

protected override async Task OnInitializedAsync()
{
    var t1 = Task.Run(async () => 
      { Item1State = await _service.GetItem1(); 
        Item1Loaded = true; // you can probably derive this from Item1State
        await InvokeAsync(StateHasChanged);
      });

    var t2 = Task.Run(async () => 
      { Item2State = await _service.GetItem2();
        Item2Loaded = true;           
        await InvokeAsync(StateHasChanged);
      });

   await Task.WhenAll(t1, t2);
}

No need to call StateHasChanged() here.

Without the ItemLoaded guards you could do this without Task.Run().

like image 108
Henk Holterman Avatar answered Nov 06 '25 15:11

Henk Holterman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!