gpt4 book ai didi

c# - 如何使 MvvmLight 命令异步?

转载 作者:太空宇宙 更新时间:2023-11-03 18:24:47 24 4
gpt4 key购买 nike

我仍然在思考 await/async,并且很难理解我如何在 MVVM 设置中使用它。我正在使用 MvvmLight,但我想这个问题适用于任何其他 MVVM 框架。

假设我有一个显示宠物列表的 WPF 应用程序。我有一个 RefreshCommand,它从 WCF 服务刷新列表。 UI 有一个指示器来显示它正忙,并且它绑定(bind)到 View 模型上的 IsBusy bool 属性。我的命令代码目前看起来像这样......

  BackgroundWorker bw = new BackgroundWorker();
IsBusy = true;
bw.DoWork += (_, __) => {
Pets = _petService.GetPets();
IsBusy = false;
};
bw.RunWorkerAsync();

Pets 是 View 模型上的一个 ObservableCollection 属性。

我想使用 await/async 关键字,并取消 BackgroundWorker。我已经搜索和阅读,阅读和搜索,并且感到困惑。我看到的大多数文章/博客文章/等等似乎都要求您创建自己的 ICommand 异步实现。为什么这是必要的?鉴于 MVVM 和 ICommand 内置于 .NET 框架中,当然也应该内置使用 async/await 的能力,而不需要创建我们自己的异步命令类。

我是否遗漏了什么,或者这真的是唯一的方法吗?

我尝试了以下方法,但没有用...

  private async void LoadAsyncData() {
IsBusy = true;
Task<ObservableCollection<Pet>> t = GetPetsAsync();
Pets = await t;
IsBusy = false;
}

private async Task<ObservableCollection<Pet>> GetPetsAsync() {
await Task.Delay(1);
return _petService.GetPets();
}

我添加了对 Task.Delay(1) 的调用,因为编译器警告我该方法将被称为同步。

数据已加载,但 UI 从未响应正在更改的 IsBusy 属性,因此用户看不到 UI 正忙。

谁能给个建议?

最佳答案

你最好听听编译器警告你什么,而不是把它藏起来:)在那之后无用的 await Task.Delay 方法将在 UI 线程上继续,所以它基本上仍然是同步方法 - 那这就是为什么 UI 没有响应 IsBusy 属性,它被阻止了。相反,您必须要么

  • 在后台线程上显式运行您的 _petService.GetPets:

    private async void LoadAsyncData() {
    IsBusy = true;
    Pets = await Task.Run(() => _petService.GetPets());
    IsBusy = false;
    }
  • (更好)通过添加异步版本的 GetPets 更改您的 petService:

    private async void LoadAsyncData() {
    IsBusy = true;
    Pets = await _petService.GetPetsAsync();
    IsBusy = false;
    }

关于c# - 如何使 MvvmLight 命令异步?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37379576/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com