RelayCommand
1. 方法返回 Task 时:RelayCommand 的 “伪异步” 执行
当你用
[RelayCommand] 标记返回 Task 的方法时,RelayCommand 会做这些事:graph TD
A[按钮点击] --> B[触发 ICommand.Execute()]
B --> C[RelayCommand 调用你的 async Task 方法]
C --> D[方法返回 Task(异步逻辑开始)]
D --> E[Execute 方法立即返回(因为 Task 是“待执行”对象,不是阻塞调用)]
E --> F[WPF 认为 Execute 已完成,但你的异步逻辑(如 ShowAsync)还在后台跑]
F --> G[模态窗口阻塞当前线程 → RelayCommand 无法感知 Task 何时完成 → 按钮状态异常]
关键误区:你以为返回
Task 是 “让 RelayCommand 等异步完成”,但实际是:Execute方法拿到Task后就直接返回了(因为Execute是 void 签名,无法 await);- 模态窗口的阻塞会打乱 WPF 的消息循环,导致按钮的 “执行中” 状态无法被正确重置,表现为 “一直按压”。
2. 方法返回 void 时:async void 的 “立即释放” 逻辑
当方法是
async void 时,执行流程变成:graph TD
A[按钮点击] --> B[触发 ICommand.Execute()]
B --> C[RelayCommand 调用你的 async void 方法]
C --> D[方法执行到 await ShowAsync() → 线程挂起,方法立即返回]
D --> E[Execute 方法同步完成 → WPF 立即释放按钮按压状态]
E --> F[异步逻辑(ShowAsync)在后台继续执行,模态窗口正常显示]
这里的核心是:
async void 方法遇到 await 会立即退出,让 Execute 方法同步完成,WPF 就能正常重置按钮状态。
浙公网安备 33010602011771号