异步触发和处理事件

Trigger and handle Event async

我目前正在开发 .net 5 Blazor 应用程序。

我使用事件将数据从一个组件传递到另一个组件。

不幸的是,我当前的逻辑是同步的 - 但我宁愿使用异步事件处理程序。

因此,我需要使用以下代码来处理我的事件:

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

是否可以在没有 Task.Run 的情况下异步处理事件?

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();
}
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;
    }
}

有没有办法异步声明和处理事件?

你知道如何解决这个问题吗?

我觉得你做事的方式很奇怪。这不是我在 Blazor 中处理事件的方式。 (也许您来自网络表单?)

通常,自定义事件的定义如下:

MyControl.razor

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

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

如果需要,消费控件中的处理程序可以是异步的:

MyPage.razor

<MyControl EventName=OnChangeHandler />

@code {
    private async Task OnChangeHandler()
    {
        await ChangeNumbers();
    }
}

基本采用 async void 处理程序:

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
}