How bad is it to open a new Form using System.Timers.Timer?
My c# WinForm application uses the Elapsed event of a System.Timers.Timer to open a new form. It was pointed out to me (in an earlier question I posted on a different topic) that this was a bad idea; it was suggested I use System.Windows.Forms.Timer.
I've changed my code in response to this suggestion and my application appears to work; however, I'm still rather low on the WinForms learning curve and I'd enjoy feedback on whether or not I've correctly changed my code. (I'm concerned because the old way--the bad way--al开发者_StackOverflow中文版so appeared to work.)
I have two forms: frmTimer and frmUser. Each form resides in a separate project in the WinForms solution. FrmTimer uses the namespace 'svchostx' and runs from svchostx.exe. FrmUser uses the namespace 'XXXUser' and runs from XXXUser.exe (where XXX is the application's name).
Is it bad to use System.Timers.Timer in this context and, if it is, then have I made the correct changes?
In frmTimer this code:
this.tmTimer= new System.Timers.Timer();
((System.ComponentModel.ISupportInitialize)(this.tmTimer)).BeginInit();
//
// tmTimer
//
this.tmTimer.Interval = 20000;
this.tmTimer.SynchronizingObject = this;
this.tmTimer.Elapsed += new System.Timers.ElapsedEventHandler(this.tmTimer_Elapsed);
private System.Timers.Timer tmTimer;
private void tmTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) {
Was replaced with this code:
this.timer1 = new System.Windows.Forms.Timer(this.components);
//
// timer1
//
this.timer1.Interval = 20000;
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
private System.Windows.Forms.Timer timer1;
private void timer1_Tick(object sender, System.EventArgs e) {
In both the old code and the new code, the timer event checks to see if certain conditions are meet, and when they're meet, then frmUser is opened. FrmUser shows a quiz screen (with math or spelling questions) that the user answers. FrmTimer is never seen and contains only logic to determine when frmUser is opened.
Also, Visual Studio's IntelliSense says this about System.Windows.Forms.Timer: "This timer is optimized for use in Windows Forms applications and must be used in a window." The last part of that sentence confuses me because frmTimer doesn't really have a window (the form is never seen). I'm not sure what is meant by 'must be used in a window'--yes, I am pretty low on the learning curve.
Any advice or help here is appreciated.
The way you are using the System.Timers.Timer
is correct. The key to making this timer work in UI scenarios is the SynchronizingObject
property. When set to null
this timer raises the Elapsed
event on a ThreadPool
thread. When set to an instance of an ISynchronizeInvoke
object it raises the event on the thread hosting that object. If that ISynchronizeInvoke
instance is none other than a control or form then the hosting thread is the thread that the control or form was created on...the main UI thread.
The System.Windows.Forms.Timer
can only be used in UI scenarios because it creates a window handle. You do not actually see this window get created, but it is there. And of course this timer always raises its Tick
event on the UI thread.
Use System.Windows.Forms.Timer
for interaction with WinForms.
System.Timers.Timer
is built for other purposes, like background operations and services, and its not synchronized with UI Threads.
Have also a look here.
Read about the three types of timers available in .net from here. There is really nothing wrong with using the System.Windows.Forms.Timer
for UI programming.
If two windows are created in the same thread, then anything which stalls the UI thread for one will stall it for both. On the other hand, controls from one window can freely manipulate the other window without requiring any explicit synchronization. If you use a forms.Timer, your new window can only be created when the UI is idle; unless you endeavor to make it otherwise, your new form will use the same thread as the one with the timer. If you use another type of timer, your new form can appear even when all other UI threads are busy; the new form will not share a thread with other forms. Note that since the form's thread won't die until the form is closed, it may be better to create a new thread (from the timer event) than hog a thread-pool thread.
精彩评论