2

I'm trying to enable a busy indicator on log in. The problem I'm having is it won't enable until everything is done executing. How can I immediately tell the thread to update the UI as soon as I log in to start the indicator asap?

 private void LoginButton_Click(object sender, RoutedEventArgs e) { this.Dispatcher.Invoke((Action)(() => { radBusyIndicator.IsBusy = true; //var backgroundWorker = new System.ComponentModel.BackgroundWorker(); //backgroundWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(backgroundWorker_DoWork); //backgroundWorker.RunWorkerAsync(); })); string error = string.Empty; long userId = 0; //Login code here.... //........... bunch of other code. etc.. } 
1
  • We will need more details. The code inside the Dispatcher doesn't bneed the Dispatcher. Most likely you are blocking the UI in 'bunch of other code'. Commented Jun 27, 2013 at 20:58

2 Answers 2

9

The UI will update as soon as the UI thread is free. There is no need for Dispatcher.Invoke in this case, as you're already in the UI thread.

The key here is to move the "work" into a background thread, ie:

private void LoginButton_Click(object sender, RoutedEventArgs e) { radBusyIndicator.IsBusy = true; LoginButton.IsEnabled = false; // Prevent clicking twice string error = string.Empty; long userId = 0; // Start this in the background var task = Task.Factory.StartNew(()=> { //Login code here.... //........... bunch of other code. etc.. }); // Run, on the UI thread, cleanup code afterwards task.ContinueWith(t => { // TODO: Handle exceptions by checking t.Exception or similar... radBusyIndicator.IsBusy = false; LoginButton.IsEnabled = true; }, TaskScheduler.FromCurrentSynchronizationContext()); } 

If you're using C# 5, you can simplify this by making your login and other code asynchronous:

private async void LoginButton_Click(object sender, RoutedEventArgs e) { radBusyIndicator.IsBusy = true; LoginButton.IsEnabled = false; // Prevent clicking twice long userId = 0; // Call async method with await, etc... string error = await DoLoginAsync(userId); var result = await BunchOfOtherCodeAsync(); radBusyIndicator.IsBusy = false; LoginButton.IsEnabled = true; } 
Sign up to request clarification or add additional context in comments.

Comments

0

You can use BAckground Worker Thread and subsribe its two eventHandlers to your events which you want to work on.. for eg-

BackgroundWorker Worker=new BackgroundWorker(); worker.DoWork+=Yorevent which will do the timeTaking Task(); Worker.RunWorkerCompleted+=YOurEvent which will Update your UI after the work is done(); worker.RunWorkerAsync(); 

this way it will not cause any thread Error too..

Just Enable your BusyIndicator as Your TimeTaking TAsk start and when the timeTaking Task is done just Disable your Busy Indicator in RUnWorkerCompleted Event.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.