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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With