是否应该为异步委托分配一个单独的事件?

Should a separate event be allocated for an asynchronous delegate?

对于代码中的异步委托,我处处做了以下处理:

public class SomeCaller
{
    public event Action SomeChanged;
    public event Func<Task> SomeChangedAsync;

    //If in Caller async method
    public async Task SomeMethodAsync()
    {
        SomeChanged?.Invoke();
        if (SomeChangedAsync != null)
            await SomeChangedAsync();
    }

    //if in Caller synchronous method
    public void SomeMethod()
    {
        SomeChanged?.Invoke();
        if (SomeChangedAsync != null)
            Task.Run(async () => await SomeChangedAsync());
    }
}

这样的解决方案(为异步分离事件)是否有任何意义,或者这是一个糟糕设计的例子? 如果这很糟糕,那么我想了解为什么以及如何最好地调用异步委托?

SomeChangedAsync 事件的调用未正确实现。如果有多个事件处理程序,则只会等待最后一个附加的处理程序。要等待所有处理程序,您必须使用方法 GetInvocationList 获取它们,然后决定您要如何调用和等待它们。这是一个顺序方法:

public async Task SomeMethodAsync()
{
    SomeChanged?.Invoke();

    Delegate[] delegates = SomeChangedAsync?.GetInvocationList();
    if (delegates != null)
    {
        var taskFactories = delegates.Cast<Func<Task>>().ToArray();
        foreach (var taskFactory in taskFactories)
        {
            var task = taskFactory();
            await task;
        }
    }
}

您也可以一次调用并等待它们(使用 Task.WhenAll),正如建议的那样

is this an example of poor design?

可能 是一个糟糕的设计。同步版本在线程池线程(而不是引发事件的任何线程)上引发委托,并将它们引发为即发即弃,这意味着任何异常都将被默默地吞噬和忽略。这通常很糟糕。

If this is bad, then I would like to understand why and how best to call async delegates?

您需要异步调用异步委托 - 从异步方法。虽然有 some hacks that work in most situations.

,但并不总是可以安全地同步调用异步方法(或委托)