pjrage
Jun 5th, 2007, 09:07 AM
I'm trying to learn more about threading by thinking of my own examples then trying them out.
I'm currently attempting to get something like a timer to work by using the Thread.Sleep method for the thread.
I want the timer to flash a label on my main form, but that is the problem. The reason I'm trying this instead of a timer is to have a different flash "on" time than "off" time, ie 500ms "on," 250ms "off" then repeat. This could be done with 2 timers on the main thread and would probably be OK but I'm just trying to learn threading.
To get the thread setup I have:
private Thread thread_flashy = null
in Form.Load..
thread_flashy = new Thread(new ThreadStart(Flashy));
thread_flashy.IsBackground = true;
thread_flashy.SetApartmentState(ApartmentState.STA);
in Button1.Click..
if (thread_flashy.IsAlive)
thread_flashy.Resume();
else
thread_flashy.Start();
private void Flashy()
{
while (true)
{
Thread.Sleep(500);
if (Label1.Visible)
{
Label1.Visible = false;
Thread.Sleep(250);
Label1.Visible = true;
}
}
}
The problem is that I cannot do any cross thread calls. I used method invoker so Flashy looked like:
private void Flashy()
{
while (true)
{
if (this.InvokeRequired)
{
this.Invoke(new MethodInvoker(Flashy));
}
else
{
Thread.Sleep(500);
if (Label1.Visible)
{
Label1.Visible = false;
Thread.Sleep(250);
Label1.Visible = true;
}
}
}
}
This freezes up the program. I'm guessing because Invoke makes the particular function (Flashy) run on the main thread (since that is the thread which is calling Invoke)? And then, the "while (true)" locks it up. To support this theory, if I take out the "while (true)" block, it runs and blinks fine just once but will not repeat.
So what I'm wondering is... how can I get this to work? If I could add the label (Label1) somehow to the thread_flashy thread so that it is not a cross-thread call, that would work right? But could I still display it on the main form?
Maybe I'm going about this all wrong? Is there a simpler way? Another way to use a while (true) to loop, but that doesn't lockup the program? I guess I could throw an Application.DoEvents() in there but that seems like a not-the-right-way-at-all way to do this.
Also, can anyone confirm that using Invoke forces the function to run on a different thread? If this is the case, then doesn't using Invoke (for cross-thread calls) defeat the purpose of using a separate thread?
And sorry for being so ignorant about threading, I'm so new to it :eek2: :eek: This is probably a silly question overall :ehh:
I'm currently attempting to get something like a timer to work by using the Thread.Sleep method for the thread.
I want the timer to flash a label on my main form, but that is the problem. The reason I'm trying this instead of a timer is to have a different flash "on" time than "off" time, ie 500ms "on," 250ms "off" then repeat. This could be done with 2 timers on the main thread and would probably be OK but I'm just trying to learn threading.
To get the thread setup I have:
private Thread thread_flashy = null
in Form.Load..
thread_flashy = new Thread(new ThreadStart(Flashy));
thread_flashy.IsBackground = true;
thread_flashy.SetApartmentState(ApartmentState.STA);
in Button1.Click..
if (thread_flashy.IsAlive)
thread_flashy.Resume();
else
thread_flashy.Start();
private void Flashy()
{
while (true)
{
Thread.Sleep(500);
if (Label1.Visible)
{
Label1.Visible = false;
Thread.Sleep(250);
Label1.Visible = true;
}
}
}
The problem is that I cannot do any cross thread calls. I used method invoker so Flashy looked like:
private void Flashy()
{
while (true)
{
if (this.InvokeRequired)
{
this.Invoke(new MethodInvoker(Flashy));
}
else
{
Thread.Sleep(500);
if (Label1.Visible)
{
Label1.Visible = false;
Thread.Sleep(250);
Label1.Visible = true;
}
}
}
}
This freezes up the program. I'm guessing because Invoke makes the particular function (Flashy) run on the main thread (since that is the thread which is calling Invoke)? And then, the "while (true)" locks it up. To support this theory, if I take out the "while (true)" block, it runs and blinks fine just once but will not repeat.
So what I'm wondering is... how can I get this to work? If I could add the label (Label1) somehow to the thread_flashy thread so that it is not a cross-thread call, that would work right? But could I still display it on the main form?
Maybe I'm going about this all wrong? Is there a simpler way? Another way to use a while (true) to loop, but that doesn't lockup the program? I guess I could throw an Application.DoEvents() in there but that seems like a not-the-right-way-at-all way to do this.
Also, can anyone confirm that using Invoke forces the function to run on a different thread? If this is the case, then doesn't using Invoke (for cross-thread calls) defeat the purpose of using a separate thread?
And sorry for being so ignorant about threading, I'm so new to it :eek2: :eek: This is probably a silly question overall :ehh: