Hello, I am using Visual Studio 2005 .Net, coding in C#. I am working
through the threading walkthrough:
ms-help://MS.VSCC.v80/MS.MSDNQTR.v80.en/MS.MSDN.v80/MS.VisualStudio.v80.en/dv_fxmclicc/html/7bc03b7b-d680-499b-8179-5f414b2d650c.htm
and have been able to get that to work as designed. However, I coded up a
slight variant of that example to update the GUI while each thread is running
rather than only at the end of each thread. My experience is that the GUI is
locked up while each thread is running, though. I have a simple Windows App
form with 2 buttons, 2 text boxes, and 2 labels, and then a class called
Loopy (analogous to the walkthrough Calculator class) [attached below]. My
intention is to loop from 1 to N, where N in a number entered in a text box,
and then display the value of the loop variable on the GUI by updating a
label. Each button-textbox-label combo performs a different loop in a
separate thread. Is there a glaring error in the code or do I just have a
conceptual misunderstanding?
Thanks,
Don
namespace ThreadEventTest
{
public partial class Form1 : Form
{
Loopy Loopy1;
public delegate void LoopWHandler(int current);
public delegate void LoopCHandler();
public Form1()
{
InitializeComponent();
Loopy1 = new Loopy();
Loopy1.Loop1Working += new
Loopy.Loop1WorkingHandler(this.Loop1WHandler);
Loopy1.Loop2Working += new
Loopy.Loop2WorkingHandler(this.Loop2WHandler);
Loopy1.Loop1Complete += new
Loopy.Loop1CompleteHandler(this.Loop1CHandler);
Loopy1.Loop2Complete += new
Loopy.Loop2CompleteHandler(this.Loop2CHandler);
}
private void button1_Click(object sender, EventArgs e)
{
Loopy1.var1 = int.Parse(textBox1.Text);
// Disables the btnFactorial1 until this calculation is complete.
button1.Enabled = false;
Loopy1.ChooseThreads(1);
}
private void button2_Click(object sender, EventArgs e)
{
Loopy1.var2 = int.Parse(textBox2.Text);
// Disables the btnFactorial1 until this calculation is complete.
button2.Enabled = false;
Loopy1.ChooseThreads(2);
}
protected void Loop1WHandler(int current)
// Displays the returned value in the appropriate label.
{
this.BeginInvoke(new LoopWHandler(L1WHandler), new Object[] {
current });
}
protected void Loop2WHandler(int current)
{
this.BeginInvoke(new LoopWHandler(L2WHandler), new Object[] {
current });
}
protected void Loop1CHandler()
// Displays the returned value in the appropriate label.
{
this.BeginInvoke(new LoopCHandler(L1CHandler), new Object[] {});
}
protected void Loop2CHandler()
{
this.BeginInvoke(new LoopCHandler(L2CHandler), new Object[] {});
}
public void L1WHandler(int current)
{
label1.Text = current.ToString();
}
public void L2WHandler(int current)
{
label2.Text = current.ToString();
}
public void L1CHandler()
{
button1.Enabled = true;
}
public void L2CHandler()
{
button2.Enabled = true;
}
}
}
namespace ThreadEventTest
{
public partial class Loopy : Component
{
public int var1;
public int current1;
public int var2;
public int current2;
public delegate void Loop1WorkingHandler(int current);
public delegate void Loop2WorkingHandler(int current);
public delegate void Loop1CompleteHandler();
public delegate void Loop2CompleteHandler();
public event Loop1WorkingHandler Loop1Working;
public event Loop2WorkingHandler Loop2Working;
public event Loop1CompleteHandler Loop1Complete;
public event Loop2CompleteHandler Loop2Complete;
public System.Threading.Thread Loop1Thread;
public System.Threading.Thread Loop2Thread;
public void Loop1()
{
for (int i = 1; i <= var1; i++)
{
lock (this)
{
current1 = i;
}
Loop1Working(current1);
}
Loop1Complete();
}
public void Loop2()
{
for (int i = 1; i <= var2; i++)
{
lock (this)
{
current2 = i;
}
Loop2Working(current2);
}
Loop2Complete();
}
public void ChooseThreads(int threadNumber)
{
// Determines which thread to start based on the value it
receives.
switch (threadNumber)
{
case 1:
// Sets the thread using the AddressOf the subroutine
where
// the thread will start.
Loop1Thread = new System.Threading.Thread(new
System.Threading.ThreadStart(this.Loop1));
// Starts the thread.
Loop1Thread.Start();
break;
case 2:
Loop2Thread = new
System.Threading.Thread(new
System.Threading.ThreadStart(this.Loop2));
Loop2Thread.Start();
break;
}
}
public Loopy()
{
InitializeComponent();
}
public Loopy(IContainer container)
{
container.Add(this);
InitializeComponent();
}
}
}