









使用了Prism的Ioc框架。MainWindow上注册了LoadedCommand命令,绑定到窗体的Loaded事件。
但奇怪的是,所有的功能都正常,就是LoadedCommand命令没有被调用。
后面发现是因为我在MainWindow.xaml上面没有写下面的绑定:
prism:ViewModelLocator.AutoWireViewModel="True"
问题是没写这句代码的时候,为什么其它的功能和命令都是正常的,唯独这个LoadedCommand命令没有被调用?
问了AI,AI给出来的答案是,没有指定的时候,运行这个窗体的时候,框架本身也是会去绑定ViewModel到DataContext上,但绑定的工作发生在Loaded事件之后。
然后窗体的Loaded事件一般只会触发一次,所以就错过了。
Catch 能捕获到的前提是:异常必须在 DelegateCommand.Execute() 这条同步调用链里“直接抛出来”。
在你这行代码里:
new DelegateCommand(OnOpenSourceFolder, ...) 的 Execute 委托类型是 Action(同步、无返回值).Catch(CatchError) 本质上就是在 Execute 外面包一层 try/catch,只能抓到 同步抛出的异常一旦你把 OnOpenSourceFolder 改成 async,常见会出现两种情况,都会让 Catch 抓不到:
async void:异常会在 await 之后的“续体”里抛到 SynchronizationContext/Dispatcher 上,已经不在 Execute() 的 try/catch 范围内了(所以 Catch 看不到)。async Task 但用 DelegateCommand 去绑:因为 DelegateCommand 只收 Action,你写 new DelegateCommand(async () => await XxxAsync()) 时,编译器会把这个 lambda 变成 async void 来匹配 Action,结果仍然回到上一条,异常不会被 Catch 捕获。要让异常可控,有两类正确做法:
DelegateCommand.FromAsyncHandler(Func<Task>)(如果你当前 Prism 版本支持),这样命令内部会等待 Task,异常就能在命令链路里处理。await 包在 try/catch 里,然后在 catch 里调用你的 CatchError(ex)(这是最通用、跟 Prism 版本无关的办法)。补充:如果你不捕获,async void 的异常通常最终会走到 Application.DispatcherUnhandledException(UI 线程)或 TaskScheduler.UnobservedTaskException(任务未观察到异常)这类全局兜底处理,而不是走 DelegateCommand.Catch。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。