2015-05-15 3 views
2

В приложении wpf, выполненном из калибровочных микро- и телериковых элементов управления. У меня есть разные экраны, которые загружают данные из удаленной службы, а затем отображают данные в gridview/fill comboboxes. Я использую операторы синхронизации/ожидания для выполнения операций поиска загрузки, но я почти уверен, что у него есть узкое место. Doing ждет меня основной поток пользовательского интерфейса, чтобы ждать Syncronization с рабочим потоком ... Рассмотрим этот образецАсинхронные операции и обновление пользовательского интерфейса

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, которое связано через соглашение с индикатором занятости, как его можно правильно настроить? благодаря

Update # 1:

I'n мой реальный код я

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 ... не должны были быть на workthread?

+0

Если ваша желаемая оптимизация будет работать с двумя параллельными потоками фона вместо одного ?, вы можете использовать метод 'System.Threading.Tasks.Task.WhenAll()'. Присвоение 'IsBusy' выглядит нормально, но при условии, что ваш ViewModel реализует' INotifyPropertyChanged', вам нужно что-то вроде 'onPropertyChanged (« IsBusy »)' каждый раз, когда вы устанавливаете контент свойства, чтобы уведомить XAML «View» –

+0

OT: поместите логику внутри try ... finaly block, поэтому вы всегда устанавливаете IsBusy в false, событие, если возникает исключение: 'IsBusy = True; try {....} finally {IsBusy = False;} ' – Liero

ответ

5

В этом случае у меня первая задача загружена, а затем вторая без параллелизма ... как я могу ее оптимизировать?

Вы хотите параллелизм, а не параллелизм. Вместо того, чтобы в ожидании каждой задачи последовательно, вы можете ждать на них, как с помощью 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 собственность, которая с помощью связанного конвенции занятому индикатора, как это может быть правильно установлен?

Обычно элементы, связанные через соглашение, должны реализовать INotifyPropertyChanged, чтобы обновить привязку xaml, чтобы значение было обновлено.

+0

Да, это связано с соглашением Caliburn Micro и да, он реализует INotiftyPropertyChanged ... лучше всего попытаться поймать внутри репо? что произойдет, если LoadStates завершится с Task.WhenAll? – advapi

+0

Это зависит от ваших проектных решений. Если вы обрабатываете исключения на уровне репо, сделайте это. Если вы обрабатываете исключения в бизнес-слое, вам нужно обернуть «LoadAsync» в try-catch и обработать его там. –

+0

, но если что-то не удается выполнить в Задаче [], когда все это останавливает другие потоки правильно? он не сбрасывает исключение aggreagate, поскольку я видел – advapi

Смежные вопросы