Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 是否应为异步委托分配单独的事件?_C#_.net_Events_Async Await_Delegates - Fatal编程技术网

C# 是否应为异步委托分配单独的事件?

C# 是否应为异步委托分配单独的事件?,c#,.net,events,async-await,delegates,C#,.net,Events,Async Await,Delegates,对于代码中的异步委托,我在任何地方都执行以下操作: public class SomeCaller { public event Action SomeChanged; public event Func<Task> SomeChangedAsync; //If in Caller async method public async Task SomeMethodAsync() { SomeChanged?.Invoke();

对于代码中的异步委托,我在任何地方都执行以下操作:

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;
//如果在调用方异步方法中
公共异步任务SomeMethodAsync()
{
某些更改?.Invoke();
if(SomeChangedAsync!=null)
等待某些更改同步();
}
//调用方同步方法中的if
公共方法()
{
某些更改?.Invoke();
if(SomeChangedAsync!=null)
运行(async()=>等待SomeChangedAsync());
}
}
这样的解决方案(将事件分离为异步)有什么意义吗?或者这是一个糟糕设计的例子吗?
如果这不好,那么我想了解为什么以及如何最好地调用异步委托?

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

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;
        }
    }
}
公共异步任务SomeMethodAsync() { 某些更改?.Invoke(); Delegate[]delegates=SomeChangedAsync?.GetInvocationList(); 如果(委托!=null) { var taskFactories=delegates.Cast().ToArray(); foreach(TaskFactorys中的var taskFactory) { var task=taskFactory(); 等待任务; } } }
您还可以一次调用并等待它们(使用
Task.whalll
),正如建议的那样。

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

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;
        }
    }
}
公共异步任务SomeMethodAsync() { 某些更改?.Invoke(); Delegate[]delegates=SomeChangedAsync?.GetInvocationList(); 如果(委托!=null) { var taskFactories=delegates.Cast().ToArray(); foreach(TaskFactorys中的var taskFactory) { var task=taskFactory(); 等待任务; } } } 正如建议的那样,您还可以一次调用并等待它们(使用
Task.WhenAll

这是一个糟糕设计的例子吗

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

如果这不好,那么我想了解为什么以及如何最好地调用异步委托

您需要从异步方法异步调用异步委托。同步地安全地调用异步方法(或委托)并不总是可能的,尽管有

这是一个糟糕设计的例子吗

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

如果这不好,那么我想了解为什么以及如何最好地调用异步委托

您需要从异步方法异步调用异步委托。同步地安全地调用异步方法(或委托)并不总是可能的,尽管有