Using Visual Studio 2015, visual C# windows application.
I need a timer that empties a queue in the main thread because some UI components are modified. I coded this:
public Form1()
{
InitializeComponent();
Q = new ConcurrentQueue<amsg>();
timer = new System.Timers.Timer(100);
timer.Elapsed += timer_Elapsed;
timer.Enabled = true;
}
void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
clsUdpMsg msg;
while (Q.TryDequeue(out msg)) handleRx(msg);
}
but the Elapsed event executes in a worker thread...?
If I put a timer on the main form at design time the generated prototype is slightly different:
private void timer1_Tick(object sender, EventArgs e)
{
amsg msg;
while (Q.TryDequeue(out msg)) handleRx(msg);
}
but this one DOES execute in the main thread context.
The question extends to any thread that creates a timer this way; I thought a timer created in a thread executes the elapsed event in the same thread context. Am I missing something?
Quick edit: I see where these are different timers, System.Timers.Timer and Windows.Forms.Timer. So - how do I reliably create timers that will execute in the thread where I create them?
Yeah, you're just dealing with two separate Timer
classes. System.Windows.Forms.Timer
fires its Tick
event on the main thread and System.Timers.Timer
fires its Elapsed
event on a background thread. The advantage of System.Windows.Forms.Timer
is that it hides the threading; the advantage of System.Timers.Timer
is that it doesn't require a message pump to work.
You ask, "How do I reliably create timers that will execute in the thread where I create them?" Well, this is easy when you have a Windows Forms GUI and are starting the Timer on the UI thread: just use System.Windows.Forms.Timer
. If you don't have a message pump to take advantage of, you have to use a System.Timers.Timer
and basically the only way to run something on the main thread when the timer fires its Elapsed
event is to recreate something like a message loop in your main thread--have it sit, maybe waiting for a Monitor.Pulse
or some other kind of notification from the timer thread. But this means your main thread won't be getting anything useful done in the meantime...