Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update UI before running the rest of method

I have a long-running operation that have to be done in UI thread (involves UI elements that cannot be freezed). I want to display a busy indicator before running the operation.

busyIndicator.Visibility = Visibility.Visible;
LongRunningMethod();
busyIndicator.Visibility = Visibility.Collapsed;

Of course this does not work because rendering does not occur until the operation finishes. I tried to use Task.Yield() to run the rest of method asynchronously:

busyIndicator.Visibility = Visibility.Visible;
await Task.Yield();
LongRunningMethod();

This also does not work, as far as I understand, because the rest of the method is prioritized higher than rendering operation.

How can I do it using TPL?

UPD: LongRunningMethod cannot be run in a separate thread by its nature (works with complex WPF 3D models), and anyway I cannot afford to make changes in it now. So please don't offer solutions based on running it completely or partially on a separate thread.

like image 428
Aleksey Shubin Avatar asked Dec 11 '14 08:12

Aleksey Shubin


1 Answers

If you want to break UI method execution, then you have to use async/await.

Something like (untested)

busyIndicator.Visibility = Visibility.Visible;
await Task.Run(() => await Task.Delay(1)); // here method will exit and repaint will occurs
LongRunningMethod();
busyIndicator.Visibility = Visibility.Collapsed;

But depending on how long method runs, you may want to put it completely into another thread (Task, BackgroundWorker) and only invoke methods when you need to be in UI thread.

like image 62
Sinatr Avatar answered Nov 15 '22 16:11

Sinatr