RB1987
RB1987

Reputation: 55

Running time consuming task + update winform

I have the following scenario:

  1. A Dialog window calls a time consuming Network task
  2. Wait for task result

At the same time I would like to update a progress bar or a textbox with some status -- So I tried the following:

    • Backgroundworker -> Progress bar in BW
    • Network Task in UI THREAD
  1. -
    • Tasks -> Network function
    • Background worker -> progress bar

In Both cases my GUI doesnt update till the task result is fetched. Would really appreciate if you can point me in the right direction..

private void button1_Click ( object sender, EventArgs e )
{
   bw.RunWorkerAsync(); // Updates a textbox
   Task<bool> test2 = new Task<bool>( () => _AuthHandler( sender, e, textBox1.Text, textBox2.Text ) );
   try
        {
            test2.Start();
            bool result = test2.Result;
            //bool result = _AuthHandler.Invoke( sender, e, textBox1.Text, textBox2.Text );
            if ( result )
            {

                //Do Somethin..
            }
         }
    catch(Exception e) {
        //Do Something
    }
}
// -------BW TEST CODE --------//
    public void  smthn ()
    {
        textBox3.Text += ".";
    }
    void bw_DoWork ( object sender, DoWorkEventArgs e )
      {
          for(int i = 0;; i++) 
          {
              bw.ReportProgress( i );
              Thread.Sleep( 250 );
          }
       }

    bool result = false;
    void bw_RunWorkerCompleted ( object sender, RunWorkerCompletedEventArgs e )
    {
        MessageBox.Show( "Result Set" );
        result = (bool)e.Result;
    }
    void bw_ProgressChanged ( object sender, ProgressChangedEventArgs e )
    {
        if ( textBox3.InvokeRequired )
        {
            this.Invoke( new Action( smthn ) );
        }
        else
        {
            smthn();
        }
    }

Upvotes: 0

Views: 407

Answers (3)

RB1987
RB1987

Reputation: 55

Thanks Guys.. I realized I was blocking the UI thread. SO I have made a generic class with two Background workers, progress events, bar and an on-completed event -> Which invokes the post-processing functions. I guess this is the method most of you are recommending.

Though are there any alternatives? What about async/await

Upvotes: 0

Servy
Servy

Reputation: 203830

You're blocking the UI thread until some non-UI work has completed. Don't do that. Have the UI thread do UI work, schedule non-UI work to be done in another thread, and then have it just do nothing; it'll go back to handling other UI events.

The BackgroundWorker is specifically designed for having a UI do some non UI work and the update the UI with progress or results. Have the DoWork method of the BGW do your actual work, update the progress bar in the updated handler, and do display the results in the completed handler. The BGW will take care of running all events besides the DoWork event in the UI thread, so you don't need to manually invoke to the UI thread.

The reason that your code isn't working is because you're blocking the UI thread by waiting on the task, and since it's blocked, the UI updates scheduled from the BGW's progress event don't have an opportunity to run until the whole thing finishes.

Upvotes: 1

Cam Bruce
Cam Bruce

Reputation: 5689

Your Network task should be run in the background thread by using the DoWork() method, calling ReportProgress() as needed Then, in your main UI thread, subscribe to the ProgressChanged event, and update your ProgressBar

Upvotes: 0

Related Questions