Blazor WASM中异步事件调用的await模式是否有效?
问题解答
你当前的实现属于巧合生效,并非可靠的通用方案,原因如下:
.NET中的多播异步委托(比如你定义的Func<Customer,Task>事件),调用Invoke方法时并不会自动等待所有订阅者的异步操作完成。它会依次调用每个订阅者的委托,但只会返回最后一个订阅者的Task——也就是说,你await CustomerChanged.Invoke(...)时,只会等待最后一个订阅者的异步代码执行完毕,前面的订阅者可能还在后台运行,无法保证全部完成后再让ProcessCommand返回。你现在日志验证符合预期,大概率是因为当前只有一个订阅者,这种情况下Invoke返回的就是唯一订阅者的Task,await自然能等待它完成,但只要订阅者数量超过1,这个逻辑就会失效。
这个行为是.NET委托的通用特性,和Blazor WASM平台无关,在任何.NET环境下都是如此。
要实现“所有订阅者的异步代码都执行完毕后,ProcessCommand才返回”的需求,你需要手动遍历所有订阅者的委托,收集它们的Task并等待全部完成,修改后的代码如下:
public async Task<bool> ProcessCommand(ICommand cmd) { var res = await Processor.Process(cmd); if (res && CustomerChanged is not null) { // 获取所有订阅的异步委托 var handlers = CustomerChanged.GetInvocationList() .Cast<Func<Customer, Task>>(); // 调用每个委托并收集返回的Task var tasks = handlers.Select(handler => handler(cmd.Customer)); // 等待所有Task执行完成 await Task.WhenAll(tasks); } return res; }
这样修改后,不管有多少个订阅者,ProcessCommand都会等待所有订阅者的异步操作全部完成后,才会返回结果,完全符合你的需求。
内容的提问来源于stack exchange,提问作者MBeckius
相关产品推荐
相关产品推荐

