Async method is not executed in the right (expected) order

Viewed 199

I have a component with the following event:

    // MyComponent :
    [Parameter] public EventCallback<DataChangedEventArgs> OnTextChanged { get; set; }

    protected async void SomeMethod(ChangeEventArgs args)
    {
        DataChangedEventArgs evArg =new DataChangedEventArgs(args.value);
        Console.Writeline("1");
        await OnTextChanged.InvokeAsync(evArg);
        Items = evArg.Data; // <=== problem here: Data is always null.
        Console.Writeline("4");
    }

When I use and handle the OnTextChanged event on another component, I set the Data property of DataChangedEventArgs:

 // AnotherComponent that uses MyComponent:
 public async void theTextChanged(DataChangedEventArgs args)
 {
      //...
      Console.Writeline("2");
      args.Data = await GetAPersonAsync(); // or some other object
      Console.Writeline("3");
 }

Now I expect Items to be set to the Person (the line Items = evArg.Data). But Data is always null, which means the changes that have been made to args.Data(which is a reference type) in event handler are not accessible in the invoking method the SomeMethod.

Can anyone help me with that ?

UPDATE: I think it has something to do with async method, as the console result is not as I expect (1,2,3,4):

console:
1
2
4
3
2 Answers

To add some meat to @Mister Magoo's answer, I believe the Blazor code for the event handlers looks something like this (simplified for clarity):

var task = InvokeAsync(EventMethod);
StateHasChanged();
if (task.Status != TaskStatus.RanToCompletion && task.Status != TaskStatus.Canceled)
{
    await task;
    StateHasChanged();
}

If your EventMethod returns a void, InvokeAsync returns a completed Task as soon as EventMethod yields. Only one StateHasChanged gets called - the if block is skipped. Anything that happens in EventMethod after the yield is not reflected in the UI until another component UI update occurs.

Related