Fork me on Github

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 就能正常重置按钮状态。
posted @ 2026-03-03 13:33  昂昂呀  阅读(15)  评论(0)    收藏  举报