Action vs EventHandler vs func for Async/已久的方法调用

发布于 2025-01-17 20:08:00 字数 1740 浏览 0 评论 0原文

我的 Connected 匿名方法实现中有 async/awaited 方法,我想知道其中哪一个最适合我的情况。我在下面举了例子,并根据我所知道的添加了信息。我的说法正确吗?我还缺少什么其他重要的东西吗?

EventHandler

对我来说唯一的缺点是匿名方法基本上是async void。是的,我们可以进行异步调用,但它们会有点“即发即忘/崩溃”。

public class Test
{
    public event EventHandler<ConnectEventArgs>? Connected;

    public ValueTask StartAsync()
    {
        Connected?.Invoke(this, new ConnectEventArgs(...))
    }
}

var test = new Test();

test.Connected += async (sender, e) => // private async void OnConnect(object? sender, ConnectEventArgs e) => BAD
{
    await SendAsync(); // fire and forget
};

await test.StartAsync();

Func

我注意到我们可以进行异步调用,而不必担心 async void。我认为这是进行异步/等待方法调用的唯一好方法。不是吗?

public class Test
{
    public event Func<Task>? Connected;

    public ValueTask StartAsync()
    {
        await (Connected?.Invoke() ?? Task.CompletedTask).ConfigureAwait(false);
    }
}

var test = new Test();

test.Connected += async () => // private async Task OnConnect()
{
    await SendAsync(); // Should be okay?
};

await test.StartAsync();

想到的 ActionEventHandler 之间的唯一区别是我们不传递 sender,而且我们也不必传递创建 EventArgs 类。

public class Test
{
    public event Action<bool>? Connected;

    public ValueTask StartAsync()
    {
        Connected?.Invoke(true);
    }
}

var test = new Test();

test.Connected += async (boolean) => // private void OnConnect(bool boolean)
{
    await SendAsync(); // fire and forget
};

await test.StartAsync();

I have async/awaited methods in my Connected anonymous method implementation and I wonder which one of these is the best to use in my case. I put examples below and added information according to what I know. Are my statements correct? Anything else important that I'm missing?

EventHandler

The only disadvantage to me is that the anonymous method is basically async void. Yes, we can have async calls, but they will be kinda "fire and forget/crash".

public class Test
{
    public event EventHandler<ConnectEventArgs>? Connected;

    public ValueTask StartAsync()
    {
        Connected?.Invoke(this, new ConnectEventArgs(...))
    }
}

var test = new Test();

test.Connected += async (sender, e) => // private async void OnConnect(object? sender, ConnectEventArgs e) => BAD
{
    await SendAsync(); // fire and forget
};

await test.StartAsync();

Func

What I notice is that we can have async calls without having to worry about async void. I think that's the only good way to have async/awaited method calls. Isn't it?

public class Test
{
    public event Func<Task>? Connected;

    public ValueTask StartAsync()
    {
        await (Connected?.Invoke() ?? Task.CompletedTask).ConfigureAwait(false);
    }
}

var test = new Test();

test.Connected += async () => // private async Task OnConnect()
{
    await SendAsync(); // Should be okay?
};

await test.StartAsync();

Action

The only difference between Action and EventHandler that comes into my mind is that we don't pass the sender and we don't have to create EventArgs classes.

public class Test
{
    public event Action<bool>? Connected;

    public ValueTask StartAsync()
    {
        Connected?.Invoke(true);
    }
}

var test = new Test();

test.Connected += async (boolean) => // private void OnConnect(bool boolean)
{
    await SendAsync(); // fire and forget
};

await test.StartAsync();

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文