Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Updating UI Thread immediately

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..

     }
like image 842
TMan Avatar asked Jun 29 '26 22:06

TMan


1 Answers

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;
 }
like image 160
Reed Copsey Avatar answered Jul 02 '26 11:07

Reed Copsey