Reputation: 2298
In a simple winform application, I call a function that endlessy create files on a button click event. I add Application.DoEvents() to the loop.
I press the red X to close the form.
the form closes, but files continue to be created ...
I think its on the buttons thread, but shouldnt it be a background one ? trying changing Thread.CurrentThread.IsBackGround to True on the loop function does not help.
Ideas ?
Upvotes: 2
Views: 6125
Reputation: 10969
A button click handler executes on the UI thread.
When you call Application.DoEvents, you let the UI thread process window messages. One effect of this is that each time your user clicks that button, a new 'instance' (stack frame) of the click handler method, along with a lot of other stack frames, get added to the stack. Like this:
{windows forms methods incl. message pump}
**ClickHandler**
Application.DoEvents
{windows forms methods incl. message pump}
**ClickHandler**
Application.DoEvents
{windows forms methods incl. message pump}
etc.
It's all pretty horrible.
If you want to run code in the background, better alternatives are to use
Upvotes: 1
Reputation: 75336
Add this form-level variable to your form's code:
private bool _StillOpen = true;
Then wrap the endless-loop code in your button click like this:
while (_StillOpen)
{
// do whatever your method does
Application.DoEvents();
}
Finally, add this code to your form's FormClosing event:
_StillOpen = false;
This will allow your form to close when you click the close button. Ideally you would want something like this to execute on a background thread, but this flag approach may be a quick fix to your current problem.
Upvotes: 2
Reputation: 5946
Did you try to call Thread.CurrentThread.Abort()
?
It is not the recommended way, but if you don't have access to the functions source code it might help (even though you say you are calling
DoEvents` from the function).
If you do have access to the source code, then you could put a check in there, to let the loop know that it has to stop.
Also, you could use the background worker
component, or create a different thread, and control it from outside (i.e. from the form)
Upvotes: 0
Reputation: 31855
Did you specifially create a new thread for that ButtonClick code? If not, then it's on the same thread as the Form, so the "X" button should stop it.
In either case, you could set a flag (isClosing), and check for that flag in your "while true" loop.
Upvotes: 0
Reputation: 1502206
The fact that you're using Application.DoEvents
is the first sign of a problem: it shows that you're doing too much in the UI thread. It's almost never appropriate in a well-structured program. The UI thread is not meant to have any long-running tasks. (Admittedly if it takes a long time to draw your UI you have little choice - but that suggests you should simplify your UI... and it's not applicable in this case, I suspect.)
Instead, you should be performing the long-running task (creating the files) in a separate thread. BackgroundWorker is a perfect fit for this - you can use it to report progress back to the UI, and the UI can call CancelAsync
method to request that it stops. You need to check the CancellationPending
property from within the worker thread, to see whether cancellation has been requested, and stop appropriately.
EDIT: Just to clarify what I believe is happening - I suspect your form is closing, but the program won't terminate until the event loop has finished. You're keeping the event loop going with your file-creation loop, hence the problem.
Note that there isn't a thread for the button - there's just one for your whole UI. (In certain cases you may need more than one UI thread, but that's rare - and you'd know it if you'd done it.)
Upvotes: 5