异步操作和 UI 更新
Async operations and UI update
在由 caliburn micro 和 telerik 控件组成的 wpf 应用程序中,我有不同的屏幕,这些屏幕从远程服务加载数据,然后在 gridview /fills 组合框中显示数据。
我正在使用 sync/await 运算符进行负载检索操作,但我几乎可以肯定它有一些瓶颈。
做 await 我有主 UI 线程等待与工作线程同步...考虑这个示例
Public class MyViewModel:Screen
{
[omiss]
Public bool IsBusy {get;set;}
Public list<Foo> DropDownItems1 {get;set;}
Public list<Foo2> DropDownItems2 {get;set;}
Public async Void Load()
{
IsBusy =true;
DropDownItems1 = await repository.LoadStates();
DropDownItems2 = await repository.LoadInstitutes();
IsBusy = false;
}
}
在那种情况下,我首先加载了任务,然后加载了第二个任务,没有并行性...我该如何优化它?
关于我的 IsBusy 属性,它通过约定绑定到繁忙指示器,如何正确设置它?
谢谢
更新 #1:
我是我真正的代码我在做
public async Task InitCacheDataTables()
{
var taskPortolio = GetPortfolio();
var taskInstitutes = GetInstitutes();
var taskStatus = GetStatus();
var taskCounterparts = GetCounterparts();
var taskCrosses = GetCrosses();
var taskCurrencies = GetCurrencies();
var taskSigns = GetSigns();
await TaskEx.WhenAll(new[] { taskPortolio, taskInstitutes, taskStatus, taskCounterparts, taskCrosses, taskCurrencies, taskSigns });
}
任务是这样的
private async Task GetPortfolio()
{
try
{
dynamicContainer.SetValue(UserContainerKeyHelper.Portfolios, await commonRepository.GetPortfoliosAsync());
}
catch (Exception ex)
{
errorHandler.HandleErrorAsync(ex);
}
}
private async Task GetInstitutes()
{
try
{
dynamicContainer.SetValue(UserContainerKeyHelper.Institutes, await commonRepository.GetInstitutesAsync());
}
catch (Exception ex)
{
errorHandler.HandleErrorAsync(ex);
}
}
调试时我发现所有方法都在 MainThread 上执行...不应该在 workerthread 上执行?
In that case I've first task loaded then second with no parallelism...how can I optimize this?
您需要并发性,而不是并行性。您可以使用 Task.WhenAll
:
等待它们,而不是按顺序等待每个任务
public async Task LoadAsync()
{
IsBusy = true;
var firstDropDownItemsTask = repository.LoadStates();
var secondDropDownItemsTask = repository.LoadInstitutes();
await Task.WhenAll(DropDownItems1Task, DropDownItems2Task);
DropDownItems1 = firstDropDownItemsTask.Result;
DropDownItems2 = secondDropDownItemsTask.Result;
IsBusy = false;
}
IsBusy property that's bound via convention to a busy indicator how can it be properly set ?
通常,通过约定绑定的项目需要实现 INotifyPropertyChanged
才能更新值已更新的 xaml 绑定。
在由 caliburn micro 和 telerik 控件组成的 wpf 应用程序中,我有不同的屏幕,这些屏幕从远程服务加载数据,然后在 gridview /fills 组合框中显示数据。 我正在使用 sync/await 运算符进行负载检索操作,但我几乎可以肯定它有一些瓶颈。 做 await 我有主 UI 线程等待与工作线程同步...考虑这个示例
Public class MyViewModel:Screen
{
[omiss]
Public bool IsBusy {get;set;}
Public list<Foo> DropDownItems1 {get;set;}
Public list<Foo2> DropDownItems2 {get;set;}
Public async Void Load()
{
IsBusy =true;
DropDownItems1 = await repository.LoadStates();
DropDownItems2 = await repository.LoadInstitutes();
IsBusy = false;
}
}
在那种情况下,我首先加载了任务,然后加载了第二个任务,没有并行性...我该如何优化它? 关于我的 IsBusy 属性,它通过约定绑定到繁忙指示器,如何正确设置它? 谢谢
更新 #1:
我是我真正的代码我在做
public async Task InitCacheDataTables()
{
var taskPortolio = GetPortfolio();
var taskInstitutes = GetInstitutes();
var taskStatus = GetStatus();
var taskCounterparts = GetCounterparts();
var taskCrosses = GetCrosses();
var taskCurrencies = GetCurrencies();
var taskSigns = GetSigns();
await TaskEx.WhenAll(new[] { taskPortolio, taskInstitutes, taskStatus, taskCounterparts, taskCrosses, taskCurrencies, taskSigns });
}
任务是这样的
private async Task GetPortfolio()
{
try
{
dynamicContainer.SetValue(UserContainerKeyHelper.Portfolios, await commonRepository.GetPortfoliosAsync());
}
catch (Exception ex)
{
errorHandler.HandleErrorAsync(ex);
}
}
private async Task GetInstitutes()
{
try
{
dynamicContainer.SetValue(UserContainerKeyHelper.Institutes, await commonRepository.GetInstitutesAsync());
}
catch (Exception ex)
{
errorHandler.HandleErrorAsync(ex);
}
}
调试时我发现所有方法都在 MainThread 上执行...不应该在 workerthread 上执行?
In that case I've first task loaded then second with no parallelism...how can I optimize this?
您需要并发性,而不是并行性。您可以使用 Task.WhenAll
:
public async Task LoadAsync()
{
IsBusy = true;
var firstDropDownItemsTask = repository.LoadStates();
var secondDropDownItemsTask = repository.LoadInstitutes();
await Task.WhenAll(DropDownItems1Task, DropDownItems2Task);
DropDownItems1 = firstDropDownItemsTask.Result;
DropDownItems2 = secondDropDownItemsTask.Result;
IsBusy = false;
}
IsBusy property that's bound via convention to a busy indicator how can it be properly set ?
通常,通过约定绑定的项目需要实现 INotifyPropertyChanged
才能更新值已更新的 xaml 绑定。