1

so i'm creating tasks and running them. but i see, when i'm doing shutdown - that the threads are just ending - i dont know in which state.

this happens when using "Tasks" or "BackgroundWorker", if i'm using Thread - then the application is not ending until my thread is really done.

that means, that i don't know how to perform a clean up properly. Should i just call the Shutdown after i notify the threads to finish? - that's a bit annoying as i want the application to "stop all UI" as soon as possible.

Thanks!

ArielB
  • 1,184
  • 2
  • 11
  • 36
  • you may perhaps use `CancellationToken`, see http://stackoverflow.com/questions/15067865/how-to-use-the-cancellationtoken-property – pushpraj Sep 02 '14 at 08:02
  • 1
    Why are you doing `Application.Current.Shutdown`? The proper way to exit from an application is to let the user close the main window. `Task` and `BackgroundWorker` by default use a background thread (a threadpool thread, in fact), which doesn't prevent the application from exiting. However, note that the alternative would be that the threads wouldn't exit at all and the process would continue running - you have to handle the graceful shutdown of all background tasks yourself. – Luaan Sep 02 '14 at 08:02
  • i do use cancellation token, but the threads are still exiting. and it's because i'm a system-tray application, i don't have a "X" button, so i implemented an "exit" context menu. how do i implement the alternative while using the Shutdown? – ArielB Sep 02 '14 at 08:05
  • @ArielB What do you expect the tasks to do? Make the mainwindow wait until they're done? They are background threads created, not foreground. – Yuval Itzchakov Sep 02 '14 at 08:15
  • well, i was using a CancellationToken and i wished to monitor it and make the cancel inside the task. The solution for this is not using a Task, but using a Thread (foreground). but i think i'll currently keep working with the background threads as is. – ArielB Sep 02 '14 at 11:09

1 Answers1

1

You shouldn't be using Application.Current.Shutdown at all. The proper way to exit from an application is to let the user close the main window. Using Shutdown is a bad idea for many reasons - you'll lose the ability to abort the shutdown, for example (the typical scenario being a form saying "You have unsaved changes").

EDIT:

The OP made it clear that his application has no main window, so using Application.Current.Shutdown is in fact appropriate. However, it should only be called after all the critical background work is safely finished (or cancelled).

Task and BackgroundWorker by default use a background thread (a thread pool thread, in fact), which doesn't prevent the application from exiting. When the process exits, all the background threads simply die - no exception, no logging, no finalization. Do not use background threads for critical tasks. However, note that the alternative would be that the threads wouldn't exit at all and the process would continue running - you have to handle the graceful shutdown of all background tasks yourself.

In other words, when the user presses Exit in your context menu, cancel any running background work, wait for it to finish properly and only call Shutdown after all that has successfully completed.

Luaan
  • 62,244
  • 7
  • 97
  • 116
  • it's because i'm a system-tray application, i don't have a "X" button, so i implemented an "exit" context menu. how do i implement the alternative while using the Shutdown? – ArielB Sep 02 '14 at 08:06
  • @ArielB But you still have a main window, even though it's hidden. So you can still call `Close` on that window. Still, you'll have to handle the shutdown of all of your threads manually. The same way, if you have some background work you don't want interrupted, you have to handle that manually. For example, showing a dialog that says "there's background work running, wait or cancel?" or something like that. In any case, *you* have to do the bookkeeping. – Luaan Sep 02 '14 at 08:07
  • i'm under WPF Application (App.XAML) - i dont have a main window to call to. and that means that i shouldn't close until the threads i want to finish will finish - this is a bit annoying as the UI will still be active (i'll need to remove the context menu from the system tray) - it sounds a bit strange – ArielB Sep 02 '14 at 08:11
  • "The lifetime of some applications may not be dependent on when the main window or last window is closed, or may not be dependent on windows at all. For these scenarios you need to set the ShutdownMode property to OnExplicitShutdown, which requires an explicit Shutdown method call to stop the application. Otherwise, the application continues running in the background." http://msdn.microsoft.com/en-us/library/system.windows.application.shutdownmode(v=vs.110).aspx – ArielB Sep 02 '14 at 08:12
  • @ArielB Well, that's easy then. Just make sure the background work is done on non-background threads. Or better, handle the background worker shutdown manually - make sure you do the cancellation and wait for the tasks to finish *before* calling `Shutdown`. You still want to notify the user, of course, especially if the background work takes more than a second or two. – Luaan Sep 02 '14 at 08:12
  • yea, that's what i thought, but sadly it will make me handle all the UI stuff (disabling the context menu manually) - not fun.. but what exactly happens in a background thread when closing an application? there is no exception? no nothing? it's just ending in the middle of an execution? – ArielB Sep 02 '14 at 08:17
  • @ArielB It might be dependent on platform and .NET version, but the behaviour I've always seen is "nothing". No exception, no finally clause executed, nothing, just like a process kill. That's the whole point, in fact - background threads are designed for being disposable at any point. Most of the .NET infrastructure threads (thread pool, GC...) are background threads for exactly that reason - there's no reason to ensure they finish when the application starts closing, which means there is no need for a complicated shutdown sequence. – Luaan Sep 02 '14 at 08:26
  • 1
    Understood. i'll call shutdown only after my important threads are done. Thanks! the answer should be edited if you want? (for other people) - as the ShutDown is the way WPF recommend to close apps. – ArielB Sep 02 '14 at 08:29