简体   繁体   中英

C# and WinForms: 'Integrity' of Form.Show() call

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM