c# - WPF 应用程序的异步和填充数据

标签 c# wpf mvvm async-await mvvm-light

我有一个 WPF 应用程序,它通过构造函数中的方法初始化 UI 的状态。但是,它永远不会从构造函数中的 Wait(); 返回。

这是我目前通过一个相当人为设计的样本所做的事情:

public class SomeViewModel
{
    public ICommand AddDataCommand { get { return RelayCommand(AddDataExecute); } }
    public ObservableCollection<int> UIData { /* Property with INotifyPropertyChanged */}   

    public SomeViewModel() 
    {
        //Load synch. here
        LoadData().Wait();      
    }

    public async Task LoadData()
    {
        UIData = await Task.Run(() => SomeService.SelectAllUIData());
    }

    public async void AddDataExecute()
    {
        //Add new data item to database on separate thread to keep UI responsive
        await Task.Run(() => SomeService.AddNewData(0));

        //Reload data from database and update UI, has to happen after AddNewData completes
        await LoadData();
    }
}

我认为它挂起是因为我实际上从未返回过 Task。但是,我不知道有什么不同的方法可以同时在构造函数和调用它的命令中异步分配 UIData。

最佳答案

如果您需要异步构造,请不要通过构造函数构造对象。使用静态工厂方法:

public class SomeViewModel
{
    private SomeViewModel() 
    { }

    public static async Task<SomeViewModel> Create()
    {
        SomeViewModel model = new SomeViewModel();
        await model.LoadData();
        return model;
    }

    public async Task LoadData()
    {
        UIData = await Task.Run(() => SomeService.SelectAllUIData());
    }

    //...
}

至于为什么您的代码不起作用,您遇到了标准的 await 死锁,您在其中阻塞了一个异步操作,该阻塞阻止了在 UI 上调用延续线程,并且有两个不同的操作,每个操作都在等待另一个继续,你会遇到死锁。这就是为什么“一直异步”而不是同步阻塞异步操作很重要。

关于c# - WPF 应用程序的异步和填充数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21437566/

相关文章:

wpf - 在 MVVM 应用程序中的 View 之间导航时如何保留 View 的完整状态?

c# - WPF 数据网格 : Save cell changes immediately with MVVM

c# - Html Agility Pack 按类获取所有元素

c# - 如何使用一组笛卡尔坐标重复运行 .NET 单元测试

c# - 从 SlimDX 迁移到 SharpDX - 效果

wpf - 使用 MVVM 和 WPF 进行逼真的可视化

wpf - WPF中的自定义按钮模板

c# - 如何从 ServiceLocator 迁移到依赖注入(inject)?具体例子

c# - confuserEx、Clickonce 和 Icon

c# - WPF 窗口在关闭后不释放内存