Click here to Skip to main content
15,868,016 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more: , +
Hello all,
I am trying to use a backgroundworker and I want to invoke a delegate to get my loadingspinner to run while I am running a query.
How would I do this?
Here is code I have?
C#
public LoginScreen()
        {
            InitializeComponent();
            backgroundWorker = new BackgroundWorker();
            backgroundWorker.DoWork += new DoWorkEventHandler(BackgroundWorker_DoWork);
            backgroundWorker.ProgressChanged += new ProgressChangedEventHandler(BackgroundWorker_ProgressChanged);            
            backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(BackgroundWorker_RunWorkerCompleted);
            backgroundWorker.WorkerReportsProgress = true;
            backgroundWorker.WorkerSupportsCancellation = true;
        }
        private void BtnLoginUser_Click(object sender, RoutedEventArgs e)
        {
//Not sure where I start my backgroundworker and invoke delegate
if (valid)
                {
                    // Start the background worker.
                    backgroundWorker.RunWorkerAsync();
                }
            }
        }
private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {   //Sometimes loading happens so fast so introduce 5 sec thread.sleep()
            for(int i = 1; i <= 10; i++)
            {
                System.Threading.Thread.Sleep(500);
                backgroundWorker.ReportProgress(i);
            }
        }
private void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {   //Start the .Gif (Play and make visible)    free to interact with UI in progressChanged. 
            LoadSpinner.Play();
            LoadSpinner.Visibility = Visibility.Visible;
            try
            {
                loginUser = SQLuserAccess.UserLogin(username, password);
                if (loginUser != null)
                {
                    if (username == loginUser.Username && password == loginUser.Password)
                    { }
                    else
                        lblInvalidText.Visibility = Visibility.Visible;
                }
                else
                    lblInvalidText.Visibility = Visibility.Visible;
            }
            catch(Exception ex) { MessageBox.Show(ex.Message.ToString()); }
        }
private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            //Stop the loading  RUNS when thread is COMPLETED can work on UI
            BtnCreateUser.Content = "Register";
            BtnLoginUser.IsEnabled = true;
            LoadSpinner.Visibility = Visibility.Hidden;
            LoadSpinner.Stop();
            LoadSpinner.Close();
            if (loginUser != null)
            {
                if (loginUser.IsAdmin)
                {
                    Window WindowAdminMenu = new AdminWindow(loginUser);
                    WindowAdminMenu.Show();
                    Close();
                }
                else if (loginUser.IsCustomer)
                {
                    Window WindowCustomerMenu = new CustomerScreen(loginUser);
                    WindowCustomerMenu.Show();
                    Close();
                }
                else
                    lblInvalidText.Content = "Invalid Account Information";
            }
            else
                lblInvalidText.Visibility = Visibility.Visible;
        }


Please help me change this to use this the correct way with invoking instead of me using a thread.sleep()

What I have tried:

Using a backgroundworker thread but using thread.sleep for my loadingspinner I want to invokea delegate instead like
C#
Application.Current.Dispatcher.Invoke(delegate
    {
        backgroundWorker.ReportProgress(); //but what do i pass in and not sure if this is it
    });
Posted
Updated 16-Dec-18 23:56pm

The UI runs in the main thread, so you can't access the UI from a different thread. So you have a flag that the Spinner Visibility is bound to using data binding, say is called IsBusy. Then you communicate to the UI via the flag. Secondly, as OriginalGriff mentioned, you then offload the long-running task to a different thread. You will need to read up on Data Binding (WPF | Microsoft Docs)[^] if you are unfamiliar.
 
Share this answer
 
Do it the other way round: display the spinner - and control it - from the main UI thread, and use the BackgroundWorker events to monitor progress and termination. The long job gets done in the BackgroundWorker, the UI in the UI thread. That way, there is no need to invoke anything!
(That's exactly what the BackgroundWorker class is there for: the progress reporting and termination events are fired on the original (UI) thread so there is no need for Invoke).
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900