2

In a wpf application made of caliburn micro and telerik controls I've different screens that load data from a remote service then show data in a gridview /fills comboboxes. I'm using a sync/await operators to make the load retrieval operations but I'm almost certain it has some bottleneck. Doing await I have the main UI thread to wait syncronization with the worker thread... Consider this sample

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; } } 

In that case I've first task loaded then second with no parallelism...how can I optimize this? About my IsBusy property that's bound via convention to a busy indicator how can it be properly set ? thanks

Update #1:

I'n my real code I do

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 }); } 

where Tasks are like

 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); } } 

While debugging I've seen that all the methods are executed on the MainThread...wasn't supposed to be on workerthread?

2
  • If your desired optimization would be running two parallel background threads instead of just one?, you can use the System.Threading.Tasks.Task.WhenAll() method. The IsBusy assignment looks okay, but assuming your ViewModel implements INotifyPropertyChanged, you'd need something like an onPropertyChanged("IsBusy") each time when you set the property content in order to notify the XAML "View" Commented May 15, 2015 at 5:14
  • OT: put the logic inside try...finaly block, so you always set IsBusy to false, event if exception occurs: IsBusy=True; try{....} finally {IsBusy=False;} Commented May 15, 2015 at 6:42

1 Answer 1

5

In that case I've first task loaded then second with no parallelism...how can I optimize this?

You want concurrency, not parallelism. Instead of awaiting each task sequentially, you can await on them both using 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 ?

Usually, items bound via convention need to implement INotifyPropertyChanged in order to update the xaml binding that a value has been updated.

Sign up to request clarification or add additional context in comments.

5 Comments

Yes it's bound via Caliburn Micro convention and yes it implements INotiftyPropertyChanged... it's best to have try catch inside the repo? what happens if LoadStates fails with Task.WhenAll?
That depends on your design decisions. If you handle exceptions at the repo level, then do that. If you handle exceptions in your business layer, you'll need to wrap LoadAsync in a try-catch and handle it there.
but if something fails in the Task[] passed to when all it stops the other threads right? it doesn't trow an aggreagate exception as far I've seen
@advapi There are no extra threads in your repo queries. I'd advise you to read the docs
Thanks, I've updated the main post since I've noticed that all goes on UI Thread

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.