Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trigger and handle Event async

I'm currently working on a .net 5 Blazor application.

I use events to pass data from one component to another.

Unfortunately my current logic is synchronous - but I would rather use an asynchronous event handler.

Thus, I need to use the following code to handle my event:

Task.Run(async () => await ChangeNumbers());

Is there a possibility to handle events asynchronously without Task.Run?

  • My State service looks like this:
public class MyComponentState
{
    public int MyNumber { get; set; }
    
    // Is there a way to declare this event Action async??
    public event Action OnChange;

    public void DoStuff(int myNumber)
    {
        MyNumber = myNumber;

        NotifyStateChanged();
    }

    private void NotifyStateChanged() => OnChange?.Invoke();
}
  • The component to handle the state looks like this:
public class MyOtherComponentDisplay : ComponentBase, IDisposable
{
    [Inject]
    public MyComponentState MyComponentState { get; set; }

    protected override void OnInitialized()
    {
        // this should all be handled async... i could use OnInitializedAsync
        MyComponentState.OnChange += OnChangeHandler;
    }

    private void OnChangeHandler()
    {
        // Is there a way to handle/declare this without Task.Run(async ...) - but async right away??
        Task.Run(async () => await ChangeNumbers());
    }

    private async Task ChangeNumbers()
    {
        // Some operations with MyComponentState.MyNumber async needed!!!

        StateHasChanged();
    }

    public void Dispose()
    {
        MyComponentState.OnChange -= OnChangeHandler;
    }
}

Is there a way to declare and handle events async?

Do you know how to solve this problem?

like image 457
azzurro123 Avatar asked Nov 15 '25 07:11

azzurro123


2 Answers

The basic adoptation would be an async void handler:

private async void OnChangeHandler()
{
    // Is there a way to handle/declare this without Task.Run(async ...) 
    // - but async right away??

    // Task.Run(async () => await ChangeNumbers());
    await ChangeNumbers();
    await InvokeAsync(StateHasChanged);  // probably needed
}
like image 155
Henk Holterman Avatar answered Nov 17 '25 22:11

Henk Holterman


The way you're doing things looks strange to me. That's not how I do events in Blazor. (Maybe you're coming from Web Forms?)

Generally, a custom event is defined like:

MyControl.razor

[Parameter]
public EventCallback<SomeType> EventName{ get; set; }

@code {
    someMethod (){
        EventName.InvokeAsync(SomeType data);
    } 
}

And the handler in the consuming control can be async if you want:

MyPage.razor

<MyControl EventName=OnChangeHandler />

@code {
    private async Task OnChangeHandler()
    {
        await ChangeNumbers();
    }
}
like image 27
Bennyboy1973 Avatar answered Nov 17 '25 20:11

Bennyboy1973