Reputation: 55
I have the following scenario:
At the same time I would like to update a progress bar or a textbox with some status -- So I tried the following:
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
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
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
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