Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Background worker proper way to access UI

I'm not sure if I'm doing this correctly, but I have the following code that I am using (click button1, do the _DoWork). The question is this: how do I call the UI to get the values of textbox1 and textbox2 as they cannot be called as they are on a different thread. Should I be using dispatchers?

    private void button1_Click(object sender, RoutedEventArgs e)
    {
        if (textBox1.Text == "")
        {
            MessageBox.Show("Please enter a username and password", "Error", MessageBoxButton.OK, MessageBoxImage.Warning);
        }
        else
        {
            bw.DoWork += new DoWorkEventHandler(bw_DoWork);
            bw.RunWorkerAsync();
        }
    }

    private void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        Console.WriteLine("asd");
        UserManagement um = new UserManagement(sm.GetServerConnectionString());
        if (um.AuthUser(textBox1.Text, textBox2.Password))
        {
            MainWindow mw = new MainWindow();
            mw.Show();
            this.Close();
        }
        else
        {
            if (um.Timeout)
            {
                MessageBox.Show("Could not connect to server, please check your configuration", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            else
            {
                MessageBox.Show("Incorrect username or password", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }

        }
    }

Should I be using background worker?

like image 801
Prisoner Avatar asked Feb 22 '11 02:02

Prisoner


People also ask

How do I run background worker?

To start the operation, call RunWorkerAsync. To receive notifications of progress updates, handle the ProgressChanged event. To receive a notification when the operation is completed, handle the RunWorkerCompleted event.

How to use BackgroundWorker in c# winforms?

To use a BackgroundWorker, you simply tell it what time-consuming worker method to execute in the background, and then you call the RunWorkerAsync method. Your calling thread continues to run normally while the worker method runs asynchronously.

Is BackgroundWorker threaded?

BackgroundWorker, is a component in . NET Framework, that allows executing code as a separate thread and then report progress and completion back to the UI.

What is BackgroundWorker in VB net?

BackgroundWorker handles long-running tasks. It does not freeze the entire program as this task executes. The BackgroundWorker type provides an excellent solution. Type notes. BackgroundWorker enables a simple multithreaded architecture for VB.NET programs.


2 Answers

You can pass data into the worker via the argument of the RunWorkerAsync call and pass data out via DoWorkEventArgs.Result...

  class AuthUserData
  {
    public string Name;
    public string Password;
  }

  private void button1_Click(object sender, EventArgs e)
  {
     var authData = new AuthUserData() { Name = textBox1.Text, Password = textBox2.Text };
     worker.RunWorkerAsync(authData);
  }

  void worker_DoWork(object sender, DoWorkEventArgs e)
  {
     // On the worker thread...cannot make UI calls from here.
     var authData = (AuthUserData)e.Argument;
     UserManagement um = new UserManagement(sm.GetServerConnectionString());
     e.Result = um;
     e.Cancel = um.AuthUser(textBox1.Text, textBox2.Password));
  }

  void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
  {
     // Back on the UI thread....UI calls are cool again.
     var result = (UserManagement)e.Result;
     if (e.Cancelled)
     {
        // Do stuff if UserManagement.AuthUser succeeded.
     }
     else
     {
        // Do stuff if UserManagement.AuthUser failed.
     }
  }
like image 176
Rusty Avatar answered Oct 12 '22 15:10

Rusty


As the name implies, the Background Worker does not run on the UI thread. You can only access UI controls when on the UI thread. An easy way to work around this issue, is to save the text box properties you need in a need a new "object" and then pass it to RunWorkerAsync. This object is available to your DoWork method in e.Argument.

However, you also have an issue with showing a form on a worker thread.

like image 34
Richard Schneider Avatar answered Oct 12 '22 16:10

Richard Schneider