This is a migrated thread and some comments may be shown as answers.

Busy Indicator Stops Animating

13 Answers 856 Views
BusyIndicator
This is a migrated thread and some comments may be shown as answers.
Anthony
Top achievements
Rank 1
Veteran
Anthony asked on 30 Jan 2013, 05:29 AM
Hi,

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

Sort by
0
Ivo
Telerik team
answered on 04 Feb 2013, 09:11 AM
Hello Anthony,

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.

0
Ian
Top achievements
Rank 1
answered on 01 Jun 2013, 01:31 PM
Hi Telerik

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  
0
Ivo
Telerik team
answered on 06 Jun 2013, 11:05 AM
Hi Ian,

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.

0
Ian
Top achievements
Rank 1
answered on 15 Jun 2013, 02:27 AM
Hi Ivo

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
0
Ivo
Telerik team
answered on 19 Jun 2013, 08:36 AM
Hi Jan,

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.

0
Mike
Top achievements
Rank 1
answered on 02 Aug 2013, 07:15 PM
Is there an update? Did the blog post ever get created? Or sample code (from Telerik or from OP)?

Thanks!
0
Mike
Top achievements
Rank 1
answered on 02 Aug 2013, 08:16 PM
More info here (Check "Multiple Windows, Multiple Threads"): http://msdn.microsoft.com/en-us/library/ms741870.aspx
0
Yana
Telerik team
answered on 07 Aug 2013, 01:46 PM
Hello Mike,

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
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
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 >>
0
Luca
Top achievements
Rank 1
answered on 07 Aug 2013, 04:38 PM
This is my personal adaptation of Abraham Heidebrecht work (see the first post),
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
0
Anthony
Top achievements
Rank 1
Veteran
answered on 07 Aug 2013, 10:27 PM
I have also adapted the Abraham Heidebrecht work, however the single threaded nature of WPF still makes this fail on some occasions in a real world application.

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.
0
Luca
Top achievements
Rank 1
answered on 09 Aug 2013, 08:17 AM
Another way to get the code working is using async/await with a little delay

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.






0
Anthony
Top achievements
Rank 1
Veteran
answered on 09 Aug 2013, 09:28 AM
The following code from also looks promising as you do not have to introduce a delay.

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.

0
Luca
Top achievements
Rank 1
answered on 12 Aug 2013, 10:16 AM
The correct way to perform a long operation on UI thread is frequently yielding, allowing the Dispatcher to perform other tasks. (http://msdn.microsoft.com/en-us/library/hh965189.aspx)

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.

Tags
BusyIndicator
Asked by
Anthony
Top achievements
Rank 1
Veteran
Answers by
Ivo
Telerik team
Ian
Top achievements
Rank 1
Mike
Top achievements
Rank 1
Yana
Telerik team
Luca
Top achievements
Rank 1
Anthony
Top achievements
Rank 1
Veteran
Share this question
or