Control.Invoke, label.Text property didn't get updated

K

kndg

Hi all,

I'm just learning to use threading but stumble on below problem.
When the worker thread start, the progressBar.Value updating fine but
not with label.Text. Can someone shed some light on me?
BackgroudWorker work just fine but I cannot use BackgroundWorker because
the code is using CompactFramework.

Thanks for any help.


using System;
using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;

namespace MyNamespace
{
public class DownloadedEventArgs : EventArgs
{
public readonly int Index;

public DownloadedEventArgs(int index)
{
Index = index;
}
}

public class Downloader
{
public event EventHandler<DownloadedEventArgs> Downloaded;
public event EventHandler<EventArgs> DownloadCompleted;

private void DownloadedInvoker(DownloadedEventArgs e)
{
if (Downloaded != null) Downloaded(this, e);
}

private void DownloadCompletedInvoker(EventArgs e)
{
if (DownloadCompleted != null) DownloadCompleted(this, e);
}

public void Download()
{
for (int i = 1; i <= 100; i++)
{
Thread.Sleep(100); // simulate long download interval
DownloadedInvoker(new DownloadedEventArgs(i));
}

DownloadCompletedInvoker(new EventArgs());
}
}

public class Foo : Form
{
private Downloader downloader = new Downloader();
private Button button = new Button();
private Label label = new Label();
private ProgressBar progressBar = new ProgressBar();
delegate void MethodInvoker();
//private BackgroundWorker backgroundWorker = new BackgroundWorker();

public Foo()
{
button.Text = "Start";
button.Location = new System.Drawing.Point(100, 100);
button.Click += ButtonClicked;

progressBar.Maximum = 100;
progressBar.Location = new System.Drawing.Point(100, 50);

label.Location = new System.Drawing.Point(100, 20);
label.Text = "Ready...";

Controls.Add(button);
Controls.Add(label);
Controls.Add(progressBar);
downloader.Downloaded += ItemDownloaded;
downloader.DownloadCompleted += DownloadCompleted;

//backgroundWorker.DoWork += new DoWorkEventHandler(DoWork);
}

public void Start()
{
Thread worker = new Thread(UpdateProgress);
worker.Start();
//backgroundWorker.RunWorkerAsync();
}

private void UpdateProgress()
{
Invoke(new MethodInvoker(downloader.Download));
}

private void ButtonClicked(object o, EventArgs e)
{
button.Text = "Downloading...";
Start();
}

private void ItemDownloaded(object o, DownloadedEventArgs e)
{
label.Text = "Downloaded item no: " + e.Index; // <--
progressBar.Value = e.Index;
}

private void DownloadCompleted(object o, EventArgs e)
{
button.Text = "Completed";
button.Enabled = false;
}

//private void DoWork(object o, DoWorkEventArgs e)
//{
// downloader.Download();
//}

[STAThread]
static void Main(string[] args)
{
Application.Run(new Foo());
}
}
}
 
P

Peter Duniho

Hi all,

I'm just learning to use threading but stumble on below problem.
When the worker thread start, the progressBar.Value updating fine but
not with label.Text. Can someone shed some light on me? [...]

Yes. You are completely disabling the whole point of creating a thread,
by having that thread execute its code via a call to Control.Invoke().
Basically, this is what happens in your program:

Main GUI Thread worker Thread
------------------ ---------------
Create form
Enter message loop
(user clicks button)
Create worker thread
Start worker thread
Return to message loop
Call Control.Invoke() with the Download()
method
Wait for Control.Invoke() to return
Execute Download() method
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top