最推荐方式是结合 ReactiveUI 与 ReactiveUI.SourceGenerators,通过 [ReactiveCommand] 特性自动生成线程安全、可取消、支持状态绑定的异步命令,天然适配 Avalonia 数据绑定,无需手动调度,自动处理 UI 更新与取消逻辑。
在 Avalonia 中,用 ViewModel 执行异步命令最推荐的方式是结合 ReactiveUI 与 ReactiveUI.SourceGenerators,通过 [ReactiveCommand] 特性自动生成线程安全、可取消、支持状态绑定的异步命令。它天然适配 Avalonia 的数据绑定机制,无需手动处理调度或 UI 线程切换。
只需在 ViewModel 中标记一个 async void 或 async Task 方法,并加上 [ReactiveCommand] 特性,Source Generators 就会自动为你生成命令对象、CanExecute 观察流、执行状态属性(如 IsExecuting)等:
async void 或 async Task,参数可带 CancellationToken
Dispatcher.UIThread.InvokeAsync 更新绑定属性,无需手动调度IsExecuting、ExecutionTask 等可观测属性,方便绑定按钮禁用/进度条在 AXAML 中直接绑定命令和状态属性即可实现响应式交互:
Command="{Binding ExecuteAsync}" 绑定触发逻辑IsE
nabled="{Binding IsNotExecuting}" 或 IsEnabled="{Binding !IsExecuting}" 控制按钮是否可点Content="{Binding Status}" 实时显示“执行中…10%”“已完成”等提示[ReactiveCommand(CanExecute = nameof(IsExecuting))] 的 CancelExecution 方法异步命令常涉及长时间运行任务,必须正确处理取消和释放:
CancellationToken.ThrowIfCancellationRequested() 主动检查中断CancellationTokenSource.CreateLinkedTokenSource(cancellationToken) 合并传入的命令级 token 和自定义逻辑finally 块中调用 _cancellationTokenSource?.Dispose(),防止内存泄漏myTextBlock.Text = "xxx"),始终走 Reactive 属性绑定虽然可以手动实现 ICommand 并在 Execute 中启动 Task.Run(async () => {...}),但这种方式容易出错:
IsExecuting、CanExecute 变化通知机制CommandParameter 或外部信号联动不复杂但容易忽略:关键不是“能不能跑异步”,而是“状态是否可观察、取消是否可传播、UI 是否安全更新”。用好 [ReactiveCommand] 就覆盖了这三点。