Ale*_*lex 2 c# wpf asynchronous mvvm
我正在使用 Entity Framework 6 在 Visual Studio 2015 中构建 MVVM Light WPF 应用程序。该应用程序具有许多调用async初始化方法的视图模型。这是一个示例视图模型:
public class MyViewModel : MyViewModelBase
{
public MyViewModel()
{
PopulateParameters();
// Other code...
}
public ObservableCollection<ParametersViewModel>
Parameters { get; private set; } =
new ObservableCollection<ParametersViewModel>();
private async void PopulateParameters()
{
var service = new MyDataService();
Parameters.Clear();
foreach(var parameter in await service.GetParameters())
Parameters.Add(parameter);
}
// Other methods and properties
}
Run Code Online (Sandbox Code Playgroud)
在MyDataService课堂上,我有这样的方法:
public async Task<ParametersViewModel> GetParameters()
{
using (var context = new MyEntities())
{
var query = (from param in context.Parameters
select new ParametersViewModel
{
// Populate ParametersViewModel properties here...
}
);
return await Task.Run(() => query);
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,视图模型的构造函数正在调用async void方法PopulateParameters()。这是非常糟糕的编程,我想改变它。但是,我不确定如何。我无法将必要的数据注入到我的所有视图模型中;有些必须执行自己的初始化,其中大部分涉及对async方法的调用。
当从视图模型的构造函数调用异步方法时,如何更改上述代码以符合最佳实践?谢谢。
更新:确保您绑定到.Result从返回的值NotifyTask.Create()。我花了一段时间才弄清楚这一点。更多信息请参见:https://msdn.microsoft.com/en-us/magazine/dn605875.aspx
我有一篇博客文章描述了“异步构造函数”的几种方法。
但在这种情况下,您真正想要的是异步数据绑定。使用NotifyTask我的Mvvm.Async 库中的类型将如下所示:
public NotifyTask<ObservableCollection<ParametersViewModel>>
Parameters { get; private set { /* with notify, such as RaisePropertyChanged() */ } }
public MyViewModel()
{
Parameters = NotifyTask.Create(() => GetParametersAsync(),
new ObservableCollection<ParametersViewModel>());
// Other code...
}
private async Task<ObservableCollection<ParametersViewModel>> GetParametersAsync()
{
var service = new MyDataService();
var result = new ObservableCollection<ParametersViewModel>();
foreach(var parameter in await service.GetParameters())
result.Add(parameter);
return result;
}
Run Code Online (Sandbox Code Playgroud)
包装NotifyTask<T>器提供了多个数据可绑定属性,例如Result包含可观察集合、IsNotCompleted用于显示加载指示器和IsFaulted/ErrorMessage用于数据绑定错误条件(如果您愿意)。