RE: Can't update foreground panel from background thread
- From: Mark R. Dawson <MarkRDawson@xxxxxxxxxxxxxxxxxxxxxxxxx>
- Date: Mon, 18 Dec 2006 20:37:00 -0800
Hi Greg,
you cannot update a control from a thread that did not create the control.
In your case you are adding the labels to the panel from a different thread
so that is probably why it is not updating automatically. What you want to
do is transfer control back to the main UI thread to update the panel, you
can do this using Invoke, so inside of backgroundWorker1_DoWork, do something
like:
void private void backgroundWorker1_DoWork(.....)
{
//Update panel
UpdatePanel();
}
private void UpdatePanel()
{
if(this.panelTemp.InvokeRequired)
{
//being called from different thread than main UI thread,
//call this function again on the main thread.
this.panelTemp.Invoke(new MethodInvoker(UpdatePanel));
}
else
{
Label label1 = new Label();
label1.Text = "Label 1 text from background thread";
label1.Location = new Point(1, 1);
label1.Size = new Size(200, 35);
panelTemp.Controls.Add(label1);
Label label2 = new Label();
label2.Text = "Label 2 text from background thread";
label2.Location = new Point(1, 15);
label2.Size = new Size(200, 35);
panelTemp.Controls.Add(label2);
}
}
Mark
--
http://www.markdawson.org
"Code like the person who maintains your code is a axe murdered - WHO KNOWS
WHERE YOU LIVE"
"Greg Larsen" wrote:
I'm trying to figure out how to modify a panel (panel1) from a.
backgroundworker thread. But can't get the panel to show the new controls
added by the backgroundwork task. Here is my code. In this code there is a
panel panel1, that I populate with a lable in the foreground. Then when I
click on "button1" a backgroundworker thread in async mode is started. When
the backgoundworker thread completes the thread returns a panel to populate
the panel1 control in the form with two controls label1 and lable 2. What I
can't figure out is how to redraw the form, or panel so the two new controls
are displayed. Does anyone know how to change my code to resolve this
problem?
Here is my code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace test
{
class Form1 : Form
{
public Form1()
{
InitializeComponent();
Label label1 = new Label();
label1.Text = "Label 1 text from foreground thread";
label1.Location = new Point(1, 1);
label1.Size = new Size(200, 35);
panel1.Controls.Add(label1);
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs
e)
{
// Simulate a long-running task by putting the thread
// to sleep a random number of times. Each time the
// thread wakes up, report the progress.
BackgroundWorker worker = (BackgroundWorker)sender;
System.Random rand = new Random();
Panel panelTemp = new Panel();
int max = rand.Next(50, 500);
for (int i = 0; i < max; i++)
{
// Cancel upon cancellation requests
if (worker.CancellationPending)
{
e.Cancel = true;
break;
}
else
{
// Sleep for 30 milliseconds
System.Threading.Thread.Sleep(30);
worker.ReportProgress((int)i * 100 / max);
}
}
// Pass up the number of iterations perform to the main thread
Label label1 = new Label();
label1.Text = "Label 1 text from background thread";
label1.Location = new Point(1, 1);
label1.Size = new Size(200, 35);
panelTemp.Controls.Add(label1);
Label label2 = new Label();
label2.Text = "Label 2 text from background thread";
label2.Location = new Point(1, 15);
label2.Size = new Size(200, 35);
panelTemp.Controls.Add(label2);
e.Result = panelTemp;
}
private void backgroundWorker1_ProgressChanged(object sender,
ProgressChangedEventArgs e)
{
backgroundProgressBar.Value = e.ProgressPercentage;
}
private void backgroundWorker1_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
MessageBox.Show(
this,
"Background processing completed with errors: " +
e.Error.Message,
"ERROR!");
else if (e.Cancelled)
MessageBox.Show(
this,
"Background processing cancelled.",
"Cancelled");
else
{
panel1 = (Panel)e.Result;
MessageBox.Show("Number of controls on Panel1 - " +
panel1.Controls.Count.ToString());
panel1.Invalidate();
panel1.Refresh();
}
}
private void button1_Click(object sender, EventArgs e)
{
// Reset progress bar
backgroundProgressBar.Minimum = 0;
backgroundProgressBar.Maximum = 100;
backgroundProgressBar.Value = 0;
panel1.Controls.Clear();
// Initiate asynchronous processing
backgroundWorker1.RunWorkerAsync();
}
private void button2_Click(object sender, EventArgs e)
{
// Cancel asynchronous processing
if (backgroundWorker1.IsBusy)
backgroundWorker1.CancelAsync();
}
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be
disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
this.backgroundProgressBar = new
System.Windows.Forms.ProgressBar();
this.backgroundWorker1 = new
System.ComponentModel.BackgroundWorker();
this.panel1 = new System.Windows.Forms.Panel();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(24, 30);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(55, 22);
this.button1.TabIndex = 0;
this.button1.Text = "button1";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// button2
//
this.button2.Location = new System.Drawing.Point(136, 30);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(59, 22);
this.button2.TabIndex = 1;
this.button2.Text = "button2";
this.button2.UseVisualStyleBackColor = true;
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// backgroundProgressBar
//
this.backgroundProgressBar.Location = new
System.Drawing.Point(24, 125);
this.backgroundProgressBar.Name = "backgroundProgressBar";
this.backgroundProgressBar.Size = new System.Drawing.Size(229,
23);
this.backgroundProgressBar.TabIndex = 2;
//
// backgroundWorker1
//
this.backgroundWorker1.WorkerReportsProgress = true;
this.backgroundWorker1.WorkerSupportsCancellation = true;
this.backgroundWorker1.DoWork += new
System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork);
this.backgroundWorker1.RunWorkerCompleted += new
System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted);
this.backgroundWorker1.ProgressChanged += new
System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged);
//
// panel1
//
this.panel1.BackColor =
System.Drawing.SystemColors.ControlLightLight;
this.panel1.Location = new System.Drawing.Point(24, 177);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(238, 50);
this.panel1.TabIndex = 3;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.panel1);
this.Controls.Add(this.backgroundProgressBar);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.ProgressBar backgroundProgressBar;
private System.ComponentModel.BackgroundWorker backgroundWorker1;
private System.Windows.Forms.Panel panel1;
}
}
- Follow-Ups:
- RE: Can't update foreground panel from background thread
- From: Greg Larsen
- RE: Can't update foreground panel from background thread
- References:
- Can't update foreground panel from background thread
- From: Greg Larsen
- Can't update foreground panel from background thread
- Prev by Date: Can't update foreground panel from background thread
- Next by Date: Re: Instant Communication in ASP.NET
- Previous by thread: Can't update foreground panel from background thread
- Next by thread: RE: Can't update foreground panel from background thread
- Index(es):
Relevant Pages
|