I am trying to write a simple multithreaded program in C#. It has a button pressing which creates a new label on form, and then a for loop runs displaying loop value in label. So if you press button 3 times, it will create 3 threads with 3 labels on form with loop.
When I press the button once, it works fine. But when I press it more than once to create more labels, it runs into following problems:
-
As soon as button is pressed more than once, it stops the loop in previous thread and runs loop of new thread. If it is multithreaded then it should not stop first loop.
-
When loop of second label is finished, it gives following error
Object reference not set to an instance of an object
Here is my complete code. The line which throws error is at the end “mylabel[tcount].Text = i.ToString();”.
Screenshot of program: https://i.stack.imgur.com/4MHOP.png
Screenshot of code https://i.stack.imgur.com/S0tQ0.png
namespace WindowsFormsApplication2{
public partial class Form1 : Form{
public Form1(){
InitializeComponent();
}
private int tcount = 0;
private int y_point = 0;
Thread[] threads = new Thread[5];
Label[] mylabel = new Label[5];
private void button1_Click(object sender, EventArgs e){
threads[tcount] = new Thread(new ThreadStart(work));
threads[tcount].Start();
}
private void work(){
if (this.InvokeRequired){
this.Invoke(new MethodInvoker(delegate{
mylabel[tcount] = new Label();
mylabel[tcount].Text = "label" + tcount;
mylabel[tcount].Location = new System.Drawing.Point(0, y_point + 15);
y_point += 25;
this.Controls.Add(mylabel[tcount]);
for (int i = 0; i < 10000; i++){
mylabel[tcount].Text = i.ToString();
Application.DoEvents();
}
}));
}
tcount++;
}
}
}
The problem is the scope of
tcount, as all threads acces the same instance of it, so as soon as the second thread starts the first thread also wirtes into the second label.Also you invoke your whole worker method which will let it run in the UI-Thread again -> not actually multithreaded…
Your worker method should look something like this: