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引发,这意味着任何异常都将被默默地吞没和忽略。那通常很糟糕
如果这不好,那么我想了解为什么以及如何最好地调用异步委托
您需要从异步方法异步调用异步委托。同步地安全地调用异步方法(或委托)并不总是可能的,尽管有