The Busy Indicator works great when you have background tasks going on. However, if you have a task that cannot be performed in the background such as updating a CollectionViewSource the animation stops.
The busy indicator should really be running in a seperate thread off the main GUI thread.
There is an example of this at http://abrahamheidebrecht.wordpress.com/2009/08/05/creating-a-busy-indicator-in-a-separate-thread-in-wpf/
Would Telerik consider updating the busy indicator to run on a seperate thread?
Thanks
Anthony
13 Answers, 1 is accepted
Thank you for your feedback.
We believe that showing the RadBusyIndicator into a separate thread is a workaround of the real issue - UI components and classes should not use the UI thread for heavy data operations. There are several possible ways to show the RadBusyIndicator while the thread is frozen in both WPF and Silverlight, but we believe we should not include workarounds in our controls.
All the best,
Ivo
the Telerik team
Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.
I am also struggling with the issue of a hanging busy indicator during longer running processes in my application.
The real issue here, and one which I believe Telerik needs to address, is the need to display an animated Busy Indicator during long running --- UI PROCESSES----.
For me, the issue arises when PRISM is used for application composition and Modules are loaded On-Demand requiring both data AND UI involvement. Module loading locks the UI thread and stops the busy animation in your control.
If the busy indicator had a "RunInOwnThread" property this would alleviate the issue.
Regards
Ian Carson
As I previously explained we believe that opening a control into a thread other than the UI thread is a workaround of another issue. It's always not a good idea to place such workarounds deeply into the control, they should be part of the application's logic. We will do our best to address this issue by providing an example how to modify and use the RadBusyIndicator into another thread.
Regards,
Ivo
Telerik
Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.
I understand your concern regarding controls and threading but would certainly welcome the example you suggest. Do you think you will post it soon?
Regards
Ian Carson
We will do our best to provide a blog post that includes a sample project demonstrating this approach before our next major release.
If you would like to implement it right now - here is the basic idea:
- Create a new transparent Window. It should not have borders and it should be positioned property.
- Open the Window into a new thread every time when you want to display the BusyIndicator during a long-lasting UI operation and close it after the operation finishes.
- Place a RadBusyIndicator into the transparent Window.
Regards,
Ivo
Telerik
Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.
Thanks!
After further investigation we found that there are some border cases which will not be covered in the described in the previous post approach and there is no easy way to implement it. I am afraid that we cannot provide a working sample for WPF at this stage.
We're sorry for the caused inconvenience.
Regards,
Yana
Telerik
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
It's only a proof of concept, but it could be a starting point.
You can download the solution example from http://sdrv.ms/15O1Dn1
void DoSomething()
{
IsBusy = true;
DoSomethingThatTakesALongTime();
}
This still fails to show the busy indicator, because the IsBusy binding to show the indicator does not fire until after the DoSomethingThatTakesALongTime() is finished.
Changing this to use the dispatcher to dispatch DoSomethingThatTakesALongTime() works most of the time, however there are still occasions where the busy indicator does not show. This doesn't really make sense, even if I dispatch at ApplicationIdle priority, it seems the binding is still not updated until after the dispatched call.
The only sure way to get this to work 100% of the time was to write a dispatcher extension method that created a timer to fire the dispatched DoSomethingThatTakesALongTime() call after a slight delay, say 300ms.
So basically if you modify your code to the extent where you can get the busy indicator to show, this works much better than any other busy indicator.
async
void
DoSomething()
{
IsBusy =
true
;
await Task.Delay(100);
DoSomethingThatTakesALongTime();
}
Obviously, if the busy indicator runs on the UI Thread, it will freeze after the delay expiration.
I've updated my example (http://sdrv.ms/15O1Dn1) to demonstrate the concept and show the differences with the busy indicator running on a separate thread.
void AllowUIToUpdate()
{
DispatcherFrame frame = new DispatcherFrame();
Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Render, new DispatcherOperationCallback(delegate(object parameter)
{
frame.Continue = false;
return null;
}), null);
Dispatcher.PushFrame(frame);
}
This was sourced from http://social.msdn.microsoft.com/Forums/vstudio/en-US/6fce9b7b-4a13-4c8d-8c3e-562667851baa/forcing-update-of-ui-before-my-function-exits.
It seemed to work pretty well, but on the odd occasion I still had the binding not update.
So, the real question here is regarding the way the entire UI performs its work.
Returning to the code example
void DoSomething()
{
IsBusy = true;
DoSomethingThatTakesALongTime();
}
this version surely works smooth
async void DoSomething()
{
IsBusy = true;
await DoSomethingThatTakesALongTime();
}
async Task DoSomethingThatTakesALongTime()
{
//simulate intensive UI payload
for (int i = 0; i < 100; i++)
{
Thread.Sleep(50); //simulate UI thread work
await System.Windows.Threading.Dispatcher.Yield();
}
}
When you have portion of UI that you cannot control (like third part controls) that are not designed to yield, i think that the only solution is running busy indicator on another thread.