如何更新异步获取的viewmodel属性?

时间:2019-03-29 15:38:52

标签: c# wpf multithreading mvvm

在我的FolderViewModel中,我有

public string FolderPath
        {
            get
            {
                if (folderPath == null)
                {
                    GetFolderPathAsync();
                    return "Loading...";
                }
                return folderPath;
            }
            set
            {
                folderPath = value;
                Changed(nameof(FolderPath));
            }
        }

GetFolderPathAsync是一种异步方法,该方法使服务器调用以获取路径并设置FolderPath。

现在在另一个类中,我创建folderviewmodels并以这种方式设置它们的路径

folderViewModel.FolderPath = parent.FolderPath+"/"+folder.Name;

问题是得到的是,路径最终被设置为“正在加载... /文件夹名”,并且从服务器中获取父文件夹的文件夹路径从“正在加载...”进行更新时,该路径永远不会更新。我该如何解决?我不是很好的线程,所以我真的不知道如何解决这个问题。我想知道是否有一种方法可以使folderPath的设置等待GetFolderPathAsync以某种方式完成?

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

属性不应启动异步操作。这就是C#不支持async属性的主要原因。有关更多信息,请参阅@Stephen Cleary's blog

如果您改为从GetFolderPathAsync方法中调用async方法,则可以await将其绑定,然后在完成数据绑定属性后将其设置为“正在加载...” 。假设GetFolderPathAsync返回TaskTask<T>

public string FolderPath
{
    get
    {
        return folderPath;
    }
    set
    {
        folderPath = value;
        Changed(nameof(FolderPath));
    }
}
...
folderViewModel.FolderPath = parent.FolderPath+"/"+folder.Name;
await folderViewModel.GetFolderPathAsync();
folderViewModel.FolderPath = "Loading...";

另一种选择是使用ContinueWith方法来创建一个在任务完成时异步执行的延续:

if (folderPath == null)
{
    GetFolderPathAsync().ContinueWith(_ => 
    {
        folderPath = "Loading...";
        Changed(nameof(FolderPath));
    });
    return folderPath;
}