If I have something like while (true) Application.DoEvents();
(it's really not exactly like that) and when I close the main form, the program stays running. How can I make the program stop running? Is there any variable like 'MustTerminate'
that I can check in my while loop to know when to finish it开发者_C百科? On real life the loop is waiting for a web page to load. I could put a timer but I don't want the program to wait for the timer to stop running if when I close the form.
Yes, this is the reason you'll always get advice to not use DoEvents(). It is far to indiscriminate about what kind of events it allows to run. Not just closing forms, pressing the button that starts that loop is a nasty problem as well.
Nevertheless, there is already code in .NET that uses DoEvents() in a loop. Form.ShowDialog(). It makes it safe by doing the equivalent of this:
foreach (Form frm in Application.OpenForms) {
if (frm != dlg) frm.Enabled = false;
}
while (dlg.DialogResult != DialogResult.None) {
Application.DoEvents();
}
Setting the Enabled property to false is what makes it safe. The user can't close forms or start the command again.
Add yourself a boolean MustTerminate property, and exit the loop when you find it true. You can set the property to True handiling the ApplicationExit event.
Nested message loops are quite tricky. They have an uncanny ability to create re-entrancy bugs which are extremely difficult to reproduce. These bugs usually live for a considerable time until an unexpected situation occurs (an older machine, memory paging out, or a different OS) which reveals the latent bug - on client machines, naturally.
The best way to handle this kind of situation is to handle an event that is triggered when the operation is complete. If there is no event already defined, you can create your own by using the SynchronizationContext
class or its wrapper the AsyncOperation
class. See the MSDN docs on the event-based asynchronous pattern for more details.
精彩评论