Reputation: 671
I have a winform application and I need to make the label backcolor blinking. I am trying to do that using a for loop and a Thread.Sleep, but does not work. Thank you for any help and advise:
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < 10; i++)
{
System.Threading.Thread.Sleep(1000); // Set fast to slow.
if (label1.BackColor == Color.Red)
label1.BackColor = Color.Transparent;
else
label1.BackColor = Color.Red;
}
}
Upvotes: 2
Views: 8143
Reputation: 291
What's happening here is that you are sleeping the GUI thread, which causes the program to hang. The GUI thread is also the thread that would be responsible for changing the background color of the label.
Here's a simple implementation that will solve this problem for you. Note that this isn't the best implementation possible, but it uses your preferred blink code implementation. For a better option than Thread.Sleep, see System.Timers.Timer or, as xxbbcc suggested, a System.Windows.Forms.Timer.
BackgroundWorker blinker;
public Form1()
{
InitializeComponent();
blinker = new BackgroundWorker();
blinker.DoWork += blinker_DoWork;
}
private void blinker_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i < 10; i++)
{
System.Threading.Thread.Sleep(1000); // Set fast to slow.
if (label1.InvokeRequired)
{
label1.Invoke((Action)blink);
}
else
{
blink();
}
}
}
private void blink()
{
if (label1.BackColor == Color.Red)
label1.BackColor = Color.Transparent;
else
label1.BackColor = Color.Red;
}
private void button1_Click(object sender, EventArgs e)
{
if (blinker.IsBusy == false)
{
blinker.RunWorkerAsync();
}
}
Upvotes: 1
Reputation: 17346
Use a UI timer, not sleep for this task. You're putting the main thread to sleep all the time and you're blocking user input with that. Using Thread.Sleep
is almost always a sign that you're doing something wrong. There are very few situations when Thread.Sleep
is correct. Specifically, putting the UI thread to sleep is never correct.
Put a Timer
component on your form and in the Tick
event, keep changing the background color of your label.
For example:
// Keeps track of the number of blinks
private int m_nBlinkCount = 0;
// ...
// tmrTimer is a component added to the form.
tmrTimer.Tick += new EventHandler(OnTimerTick);
m_nBlinkCount = 0;
tmrTimer.Interval = 1000; // 1 second interval
tmrTimer.Start();
// ...
private void OnTimerTick ( Object sender, EventArgs eventargs)
{
if (label1.BackColor == Color.Red)
label1.BackColor = Color.Transparent;
else
label1.BackColor = Color.Red;
m_nBlinkCount++;
if ( m_nBlinkCount >= 10 )
tmrTimer.Stop ();
}
Upvotes: 6