异步操作和UI更新

时间:2015-05-15 04:13:51

标签: c# wpf multithreading async-await caliburn.micro

在使用caliburn micro和telerik控件制作的wpf应用程序中,我从不同的屏幕加载来自远程服务的数据,然后在网格视图/填充组合框中显示数据。 我使用sync / 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上?

1 个答案:

答案 0 :(得分:5)

  

在那种情况下,我首先加载了第二个任务,然后没有并行性......我怎样才能优化它?

你想要并发,而不是并行。您可以使用import numpy as np import matplotlib.pyplot as plt import random def f(x, y, n): N = np.array([[x, y]]) M = np.array([[1, 0], [0, 1]]) b = np.array([[.5], [0]]) b2 = np.array([[0], [.5]]) if n == 0: return np.dot(M, N.T) elif n == 1: return np.dot(M, N.T) + b elif n == 2: return np.dot(M, N.T) + b2 elif n == 3: return np.dot(M, N.T) - b elif n == 4: return np.dot(M, N.T) - b2 xs = [] # x coordinates ys = [] # y coordinates D = {} # point multiplicities random.seed() x = 1 y = 1 for i in range(0, 100000): n = random.randint(1, 4) V = f(x, y, n) x = V.item(0) y = V.item(1) xs.append(x) ys.append(y) xi = round(x, 3) yi = round(y, 3) if (xi, yi) in D: D[(xi, yi)] += 1 else: D[(xi, yi)] = 1 plt.xlabel('x') plt.ylabel('y') plt.scatter(xs,ys, s=.05) plt.autoscale(True, True, True) plt.show()

等待它们,而不是按顺序等待每个任务
Task.WhenAll
  

通过约定绑定到忙碌指示符的IsBusy属性如何正确设置?

通常,通过约定绑定的项目需要实现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; } 才能更新已更新值的xaml绑定。