My form has a number of Timer components that I am seeking to loop through at runtime. My goal is to stop all timers on the form at once.
I tried adapting some code I had to do the same thing with controls however it doesn't appear to be working.
foreach (var tmr in this.components.Components.OfType<Timer>())
{
tmr.Stop();
}
Any help would be appreciated.
Stopping a Winforms Timer means that no more Timer messages (WM_TIMER) are posted to the message queue. But any previous WM_TIMER message still in the message Queue will be processed. So multiple Tick Events might be processed even after the Timer has been stopped when you have created Timer messages faster then they can be processed.
Update:
Checking the source reveals that the Winforms Timer swallows WM_TIMER messages when the timer has been stopped and won't fire any Tick Events then. So this is not the correct answer.
Related
I have created an event in a BackgroundWorker to send text notifications to a WinForm Panel. After the BachgroundWorker is finished I change the Panel and start the next BackgroundWorker.
My Problem is that when the BGW is finished not all event messages are arrived in my Panel.
Bevor removing the Panel I want to process all event messages.
How can I observe or check if there are more event messages in queue?
thanks for your help
PeekMessage is your friend. See https://msdn.microsoft.com/en-us/library/windows/desktop/ms644943(v=vs.85).aspx for description
Does System.Windows.Forms.Timer send WM_TIMER message ?
Basically I want to set a timer that should generate
WM_TIMER
message for every 5 seconds. I am using
System.Windows.Forms.Timer
and the
Tick
event is handled. But I am not getting WM_TIMER message in my WndProc().
Yes, WM_TIMER is what makes a Winforms Timer tick. Unobserved in your code however, it creates its own window, it doesn't use yours. It is an invisible one, the underlying .NET class is TimerNativeWindow, a private class of the Timer class. You can't ever override its WndProc(). Technically you could subclass it with NativeWindow after digging out the handle with Reflection, but that way lies dragons and should never be necessary.
I have this code:
private void timer1_Tick(object sender, EventArgs e)
{
MessageBox.Show(Thread.CurrentThread.ManagedThreadId.ToString());
}
the timer is enabled, with interval = 100.
This result in an infinite number of message boxes to appear over each other, when I was expecting them to simply BLOCK the next event until the current messagebox is closed.
In more complicated applications this could lead to unpreditable results, and its as if more than 1 thread have access to the same function, but actually it is the same thread.
Why is this happening ?
The message box is a modal dialog which pumps the message queue. And so that allows for the timer tick messages to fire, since they are posted to the GUI thread's message queue.
This is always the case for a modal dialog that is shown in the GUI thread. Since each thread has only one message queue, the modal dialog's message pump will pull of the timer tick messages.
It is happening exactly how it should. The tick event is powered by the message loop (unless you're using a threaded variant) and will be called repeatedly unless you block the message loop in some way (think Thread.Sleep or non message based code execution).
The message box doesn't block, it's just another window and as long as the message pump of the application is functioning so will the window, and so as each tick happens new dialogs can be created and stacked up.
A quick solution to this is something like:
private void timer1_Tick(object sender, EventArgs e)
{
timer1.Stop();
MessageBox.Show(Thread.CurrentThread.ManagedThreadId.ToString());
timer1.Start();
}
This would stop the timer, show a dialog and allow the timer to recover after the dialog is closed. This means you'd only get the one dialog and not a perpetual stack of them.
Does the blocking of a thread also blocks the firing and/or propagation of event fired from it?
To clarify:
On a thread I am firing an event and as a next step I let the thread fall asleep. The question is whether the firing - if stated immediately before the statement to go sleep - is also blocked to fire due to a scheduling issue (i.e. the event has been scheduled to fire but actual firing will take place in say 100 ms and before these 100 ms have been passed the thread has been fall asleep).
// Pseudo-Code
event MyHandler TheEvent;
// ...
TheEvent();
threadWaitingSignal.Wait(); // block the thread
What assumptions can I make in the above scenario regarding the firing and the delivery of the event to its subscribers ?
All listeners will receive the event before the thread sleeps. Events are fired synchronously.
In the UI thread I have a piece of code that goes like this:
SomeForm form = new SomeForm();
(...)
form.Show();
SomeForm class particularly has a System.Windows.Forms.Timer instance as a member that is being initialized by auto-generated code of InitializeComponent() that looks like this:
this.UploadStatusTimer.Enabled = true;
this.UploadStatusTimer.Interval = 1000;
this.UploadStatusTimer.Tick += new System.EventHandler(this.UploadStatusTimer_Tick);
form.Show() will in the end raise Form.Load event that is being handled by SomeForm_Load(object sender, EventArgs e).
My question is: is there a possibility that UploadStatusTime_Tick was being processed before SomeForm_Load?
InitializeComponent() is called by the constructor of the Form, so it is possible that UloadStatusTimer_Tick is already called, before you call form.Show().
If you want the timer to start after you call form.Show(), set UploadStatusTimer.Enabled = false in the designer, override OnShow and use this method to set this.UploadStatusTimer.Enabled = true.
What you are asking is "can it take longer than one second from the time I construct my form for the Load event to fire?"
Beyond the theoretical answer of "yes, this is always possible" it really comes down to how long (...) takes in your example code. The timer is going to start counting down as soon as Enabled is set to true (when it is constructed).
It's important to note that UI interactions are processed via a message pump. So thinking of the winforms timer, the timer itself is off running in the background (outside of .net even; it is using the native windows timer) and when the timer expires it sends a message to your application, which then queues a message on the message pump that says "hey, timer tick happened." Same thing applies to your form load event, it is triggered via a message on the message pump. So if the timer expires before the form "loads" then the timer message will be in front of the 'form load' message on the queue and get processed first.
If you're interested in learning more, there many articles or stack overflow questions on the winforms message pump (or message loop as some may call it).
To ensure that the timer does NOT go off before Form_Load, disable it in the designer and call timer.Start(); in the Form_Load event.
To ensure that it does go off before Form_Load, move the code in the timer_Tick function to a central method and call that from the constructor.