I am new in C#. I have two button and two label. What I want is that, When I click button1 it start counting and shows in label1. When I press button2 it resume counting under button1 and start counting under button2 and shows in label2. Here is my code
bool testt = true;
int i = 0;
int j = 0;
private void button1_Click(object sender, EventArgs e)
{
while (testt)
{
label1.Text = i.ToString();
i++;
System.Threading.Thread.Sleep(50);
if (i > 5000)
{
i = 0;
}
}
}
private void button2_Click(object sender, EventArgs e)
{
testt = false;
while (!testt)
{
label2.Text = j.ToString();
j++;
System.Threading.Thread.Sleep(50);
if (j > 5000)
{
i = 0;
}
}
}
Here the problem is when I click one button, it does not allow me to click another button. I used a global variable to detect which button was pressed. But its not working. How can I make this work?
You are doing all this on the UI thread, so you are blocking it. You need to have another thread do the actual counting and delegate the label changing to the main thread by using Control.Invoke so that the main thread has time to run the message pump. You can use the built-in BackgroundWorker or simply create a thread with either ThreadPool or TaskFactory.
I've written a short example of how this can be accomplished with LINQ and ThreadPool, it's not the best approach design-wise but it would give you a starting point on developing an adequate solution
semaphore = true;
int i = 0;
int j = 0;
private void button1_Click(object sender, EventArgs e)
{
semaphore = true;
ExecuteAsync(()=>
{
while (semaphore)
{
//Dispatch a call to the UI thread to change the label
Invoke((MethodInvoker)(() => ChangeLabel(label1, i.ToString())));
i++;
Thread.Sleep(50);
if (i > 5000)
{
i = 0;
}
}
});
}
//Executes a function on a ThreadPool thread
private void ExecuteAsync(Action action)
{
ThreadPool.QueueUserWorkItem(
obj => action());
}
private void ChangeLabel(Label label, string labelText)
{
label.Text = labelText;
}
private void button2_Click(object sender, EventArgs e)
{
semaphore = false;
ExecuteAsync(() =>
{
while (!semaphore)
{
//Dispatch a call to the UI thread to change the label
Invoke((MethodInvoker)(() => ChangeLabel(label2, j.ToString())));
j++;
Thread.Sleep(50);
if (j > 5000)
{
i = 0;
}
}
});
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With