D'Arcy Rittich
D'Arcy Rittich

Reputation: 171589

UI not updating despite use of BackgroundWorker

I am setting the .Text value of a textbox, disabling it, and then calling a BackgroundWorker to do a lengthy filesystem operation. The textbox does not update with the new text value until about halfway through the BackgroundWorker operation.

What can I do to force the texbox to show the new text value ASAP? Relevant code below:

void BeginCacheCandidates()
{
    textBox1.Text = "Indexing..."; // <-- this does not update until about 20 to 30 seconds later
    textBox1.Enabled = false;
    backgroundWorker1.RunWorkerAsync();
}

void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
    //prime the cache
    CacheCandidates(candidatesCacheFileName);
}

void backgroundWorker1_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
{
    textBox1.Text = "";
    textBox1.Enabled = true;
    textBox1.Focus();
}

Update: I resolved the issue. It was code unrelated to this - I had overridden WndProc and it was going into a loop...

Upvotes: 1

Views: 2637

Answers (3)

Steven Evers
Steven Evers

Reputation: 17226

Try invoking the change on the textbox instead of directly calling it.

textBox1.BeginInvoke(new MethodInvoker(() => { textBox1.Text = string.Empty; }));

This will cause the change to happen on the Form's thread.

Upvotes: 1

decyclone
decyclone

Reputation: 30840

Use Form.Update() method to force UI updates.

void BeginCacheCandidates()
{
    textBox1.Text = "Indexing..."; // <-- this does not update until about 20 to 30 seconds later
    textBox1.Enabled = false;
    this.Update(); // Force update UI
    backgroundWorker1.RunWorkerAsync();
}

Upvotes: 0

doobop
doobop

Reputation: 4520

Unless there's some detail I'm missing, wouldn't ReportProgress give you what you want?

void BeginCacheCandidates()
{
    textBox1.Text = "Indexing...";
    textBox1.Enabled = false;
    backgroundWorker1.ReportProgress += new ProgressChangedEventHandler(handleProgress)
    backgroundWorker1.RunWorkerAsync();
}

void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
    //prime the cache
    backgroundWorker1.ReportProgress(<some int>, <text to update>);
    CacheCandidates(candidatesCacheFileName);
}

void handleProgress(object sender, ProgressChangedEventArgs e)
{ 
    ... 
    textBox1.Text = e.UserState as String; 
    ... 
}

Upvotes: 1

Related Questions