c# - 如何更新异步获取的 View 模型属性?

标签 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。

现在在另一个类中,我创建文件夹 View 模型并以这种方式设置它们的路径
folderViewModel.FolderPath = parent.FolderPath+"/"+folder.Name;

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

谢谢您的帮助!

最佳答案

属性不应启动异步操作。这就是 async 的主要原因。 C# 不支持属性。请引用@Stephen Cleary's blog了解更多信息。

如果您改为调用 GetFolderPathAsync来自 async 的方法方法,你可以 await然后在完成后将数据绑定(bind)属性设置为“正在加载...”。这假设 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;
}

关于c# - 如何更新异步获取的 View 模型属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55420903/

相关文章:

wpf - 选定的项目未显示在组合框中

java - 如何从某个Java线程调用方法

c - Pthread 参数

c# - 我可以使用反射类型作为类型参数吗?

c# - 如何使用 Masstransit 测试基于命令和事件的系统

c# - 为什么在 ToolTip 中显示验证错误的 WPF 样式对 TextBox 有效,但对 ComboBox 却失败?

wpf - 在 WPF DataTemplate 中引用控件

android - AsyncTask 和 Thread 之间的真正区别

c# - 为 List<T>() 提供大小参数

c# - 如何使 wpf 组合框拉出特殊属性