是否应该为异步委托分配一个单独的事件?
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.
,但并不总是可以安全地同步调用异步方法(或委托)
对于代码中的异步委托,我处处做了以下处理:
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.
,但并不总是可以安全地同步调用异步方法(或委托)