Threading...

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

I'm practicing using threads under c# and have made a simple program that contains a 'System.Windows.Forms.Label' label1. This label will then be updated by a separate thread displaying a count from 1 to 10000. The program works but sometimes the numbers instead of counting from 1 to 10000 pauses at say 4000 (thread keeps running) and after sometime it goes from 4000 to say 7000. This tends to occur specially when moving the window around.

Listed below is the code. Please let me know if i'm doing something wrong. Thanks.

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;

namespace TestThread
{

public delegate void DelegateAddString(String s);
public delegate void DelegateThreadFinished();

public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button btnStartThread;

private System.ComponentModel.Container components = null;

Thread m_CalculationThread;

public DelegateAddString m_DelegateAddString;
public DelegateThreadFinished m_DelegateThreadFinished;
CalculationProcess Calculation_Process;

public Form1()
{
InitializeComponent();

m_DelegateAddString = new DelegateAddString(this.AddString);
m_DelegateThreadFinished = new DelegateThreadFinished(this.ThreadFinished);
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (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.label1 = new System.Windows.Forms.Label();
this.btnStartThread = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// label1
//
this.label1.Location = new System.Drawing.Point(16, 16);
this.label1.Name = "label1";
this.label1.TabIndex = 0;
this.label1.Text = "label1";
//
// btnStartThread
//
this.btnStartThread.Location = new System.Drawing.Point(16, 56);
this.btnStartThread.Name = "btnStartThread";
this.btnStartThread.TabIndex = 1;
this.btnStartThread.Text = "Start";
this.btnStartThread.Click += new System.EventHandler(this.btnStartThread_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.btnStartThread);
this.Controls.Add(this.label1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);

}
#endregion

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}

private void btnStartThread_Click(object sender, System.EventArgs e)
{
Calculation_Process = new CalculationProcess(this);
m_CalculationThread = new Thread(new ThreadStart(Calculation_Process.Run));
m_CalculationThread.Name = "Calculation Thread";
if(m_CalculationThread!=null)
{
this.btnStartThread.Enabled = false;
m_CalculationThread.Start();
}
}
private void AddString(String s)
{
this.label1.Text = s;
}
private void ThreadFinished()
{
this.btnStartThread.Enabled = true;
this.label1.Text = "Thread finished.";
}
}
public class CalculationProcess
{
Form1 m_form;

public CalculationProcess(Form1 form)
{
m_form = form;
}

public void Run()
{
ulong i;
String s;

for (i = 1; i <= 10000; i++)
{
s = i.ToString();
m_form.Invoke(m_form.m_DelegateAddString, new Object[] {s});
}
m_form.Invoke(m_form.m_DelegateThreadFinished, null);
}

}
}
 
I ran your code and didn't experience any delay. However, moving around the
window will create other messages that compete with updating the label. This
could cause some delay. Paint messages are low priority if there are other
messages to process.

kevin aubuchon

Robert Vasquez said:
I'm practicing using threads under c# and have made a simple program that
contains a 'System.Windows.Forms.Label' label1. This label will then be
updated by a separate thread displaying a count from 1 to 10000. The
program works but sometimes the numbers instead of counting from 1 to 10000
pauses at say 4000 (thread keeps running) and after sometime it goes from
4000 to say 7000. This tends to occur specially when moving the window
around.
Listed below is the code. Please let me know if i'm doing something wrong. Thanks.

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;

namespace TestThread
{

public delegate void DelegateAddString(String s);
public delegate void DelegateThreadFinished();

public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button btnStartThread;

private System.ComponentModel.Container components = null;

Thread m_CalculationThread;

public DelegateAddString m_DelegateAddString;
public DelegateThreadFinished m_DelegateThreadFinished;
CalculationProcess Calculation_Process;

public Form1()
{
InitializeComponent();

m_DelegateAddString = new DelegateAddString(this.AddString);
m_DelegateThreadFinished = new DelegateThreadFinished(this.ThreadFinished);
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (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.label1 = new System.Windows.Forms.Label();
this.btnStartThread = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// label1
//
this.label1.Location = new System.Drawing.Point(16, 16);
this.label1.Name = "label1";
this.label1.TabIndex = 0;
this.label1.Text = "label1";
//
// btnStartThread
//
this.btnStartThread.Location = new System.Drawing.Point(16, 56);
this.btnStartThread.Name = "btnStartThread";
this.btnStartThread.TabIndex = 1;
this.btnStartThread.Text = "Start";
this.btnStartThread.Click += new System.EventHandler(this.btnStartThread_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.btnStartThread);
this.Controls.Add(this.label1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);

}
#endregion

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}

private void btnStartThread_Click(object sender, System.EventArgs e)
{
Calculation_Process = new CalculationProcess(this);
m_CalculationThread = new Thread(new ThreadStart(Calculation_Process.Run));
m_CalculationThread.Name = "Calculation Thread";
if(m_CalculationThread!=null)
{
this.btnStartThread.Enabled = false;
m_CalculationThread.Start();
}
}
private void AddString(String s)
{
this.label1.Text = s;
}
private void ThreadFinished()
{
this.btnStartThread.Enabled = true;
this.label1.Text = "Thread finished.";
}
}
public class CalculationProcess
{
Form1 m_form;

public CalculationProcess(Form1 form)
{
m_form = form;
}

public void Run()
{
ulong i;
String s;

for (i = 1; i <= 10000; i++)
{
s = i.ToString();
m_form.Invoke(m_form.m_DelegateAddString, new Object[] {s});
}
m_form.Invoke(m_form.m_DelegateThreadFinished, null);
}

}
}
 
Robert Vasquez said:
I'm practicing using threads under c# and have made a simple program
that contains a 'System.Windows.Forms.Label' label1. This label will
then be updated by a separate thread displaying a count from 1 to
10000. The program works but sometimes the numbers instead of
counting from 1 to 10000 pauses at say 4000 (thread keeps running)
and after sometime it goes from 4000 to say 7000. This tends to occur
specially when moving the window around.

You're creating a lot of windows messages in a very short space of
time, and the CPU will be busy with your other thread for most of the
time. I suspect that what's happening is that your delegates are
correctly setting the text of the label, but because there are so many
windows messages, the paint messages generated by changing the label's
text are being collected together into one paint at a later stage.
You'll only see any change on the screen after the label has painted,
so effectively it seems to jump.

That's just a guess though - someone who knows more about exactly how
the message pump works will know more, I'm sure.
 
Hi,

Robert Vasquez said:
I'm practicing using threads under c# and have made a simple program that
contains a 'System.Windows.Forms.Label' label1. This label will then be
updated by a separate thread displaying a count from 1 to 10000. The
program works but sometimes the numbers instead of counting from 1 to 10000
pauses at say 4000 (thread keeps running) and after sometime it goes from
4000 to say 7000. This tends to occur specially when moving the window
around.
Kevin and Jon are both right.

If you want this to work, you have to update the label after setting the
text:

eg.
private void AddString(String s)
{
this.label1.Text = s;
this.label1.Update(); // direct and synchronous repaint of the
label
}

HTH,
greetings




Listed below is the code. Please let me know if i'm doing something wrong. Thanks.

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;

namespace TestThread
{

public delegate void DelegateAddString(String s);
public delegate void DelegateThreadFinished();

public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button btnStartThread;

private System.ComponentModel.Container components = null;

Thread m_CalculationThread;

public DelegateAddString m_DelegateAddString;
public DelegateThreadFinished m_DelegateThreadFinished;
CalculationProcess Calculation_Process;

public Form1()
{
InitializeComponent();

m_DelegateAddString = new DelegateAddString(this.AddString);
m_DelegateThreadFinished = new DelegateThreadFinished(this.ThreadFinished);
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (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.label1 = new System.Windows.Forms.Label();
this.btnStartThread = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// label1
//
this.label1.Location = new System.Drawing.Point(16, 16);
this.label1.Name = "label1";
this.label1.TabIndex = 0;
this.label1.Text = "label1";
//
// btnStartThread
//
this.btnStartThread.Location = new System.Drawing.Point(16, 56);
this.btnStartThread.Name = "btnStartThread";
this.btnStartThread.TabIndex = 1;
this.btnStartThread.Text = "Start";
this.btnStartThread.Click += new System.EventHandler(this.btnStartThread_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.btnStartThread);
this.Controls.Add(this.label1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);

}
#endregion

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}

private void btnStartThread_Click(object sender, System.EventArgs e)
{
Calculation_Process = new CalculationProcess(this);
m_CalculationThread = new Thread(new ThreadStart(Calculation_Process.Run));
m_CalculationThread.Name = "Calculation Thread";
if(m_CalculationThread!=null)
{
this.btnStartThread.Enabled = false;
m_CalculationThread.Start();
}
}
private void AddString(String s)
{
this.label1.Text = s;
}
private void ThreadFinished()
{
this.btnStartThread.Enabled = true;
this.label1.Text = "Thread finished.";
}
}
public class CalculationProcess
{
Form1 m_form;

public CalculationProcess(Form1 form)
{
m_form = form;
}

public void Run()
{
ulong i;
String s;

for (i = 1; i <= 10000; i++)
{
s = i.ToString();
m_form.Invoke(m_form.m_DelegateAddString, new Object[] {s});
}
m_form.Invoke(m_form.m_DelegateThreadFinished, null);
}

}
}
 
Hi,
inline
Robert Vasquez said:
By doing this will I also slow down the execution time? Thanks.

Yes, painting is fast, but it will cost you some speed, since you're are
using invoke, the workerthread waits until the called delegate is done. If
you want every single number to be visible then you can't avoid this.

Ussually when a worker thread informs the ui with progress it doens't do
that so fast/often like you do with the tight loop. Suppose you are
executing a fast function 1000 times in a worker thread, you could inform
the ui thread every 100 loops, etc, ....


HTH,
greetings


BMermuys said:
Hi,

I'm practicing using threads under c# and have made a simple program
that
contains a 'System.Windows.Forms.Label' label1. This label will then be
updated by a separate thread displaying a count from 1 to 10000. The
program works but sometimes the numbers instead of counting from 1 to 10000
pauses at say 4000 (thread keeps running) and after sometime it goes from
4000 to say 7000. This tends to occur specially when moving the window
around.
Kevin and Jon are both right.

If you want this to work, you have to update the label after setting the
text:

eg.
private void AddString(String s)
{
this.label1.Text = s;
this.label1.Update(); // direct and synchronous repaint of the
label
}

HTH,
greetings




Listed below is the code. Please let me know if i'm doing something wrong. Thanks.

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;

namespace TestThread
{

public delegate void DelegateAddString(String s);
public delegate void DelegateThreadFinished();

public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button btnStartThread;

private System.ComponentModel.Container components = null;

Thread m_CalculationThread;

public DelegateAddString m_DelegateAddString;
public DelegateThreadFinished m_DelegateThreadFinished;
CalculationProcess Calculation_Process;

public Form1()
{
InitializeComponent();

m_DelegateAddString = new DelegateAddString(this.AddString);
m_DelegateThreadFinished = new DelegateThreadFinished(this.ThreadFinished);
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (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.label1 = new System.Windows.Forms.Label();
this.btnStartThread = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// label1
//
this.label1.Location = new System.Drawing.Point(16, 16);
this.label1.Name = "label1";
this.label1.TabIndex = 0;
this.label1.Text = "label1";
//
// btnStartThread
//
this.btnStartThread.Location = new System.Drawing.Point(16, 56);
this.btnStartThread.Name = "btnStartThread";
this.btnStartThread.TabIndex = 1;
this.btnStartThread.Text = "Start";
this.btnStartThread.Click += new System.EventHandler(this.btnStartThread_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.btnStartThread);
this.Controls.Add(this.label1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);

}
#endregion

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}

private void btnStartThread_Click(object sender, System.EventArgs e)
{
Calculation_Process = new CalculationProcess(this);
m_CalculationThread = new Thread(new ThreadStart(Calculation_Process.Run));
m_CalculationThread.Name = "Calculation Thread";
if(m_CalculationThread!=null)
{
this.btnStartThread.Enabled = false;
m_CalculationThread.Start();
}
}
private void AddString(String s)
{
this.label1.Text = s;
}
private void ThreadFinished()
{
this.btnStartThread.Enabled = true;
this.label1.Text = "Thread finished.";
}
}
public class CalculationProcess
{
Form1 m_form;

public CalculationProcess(Form1 form)
{
m_form = form;
}

public void Run()
{
ulong i;
String s;

for (i = 1; i <= 10000; i++)
{
s = i.ToString();
m_form.Invoke(m_form.m_DelegateAddString, new Object[] {s});
}
m_form.Invoke(m_form.m_DelegateThreadFinished, null);
}

}
}
 
Back
Top