C# 为什么在执行Application.Current.Shutdown时线程(任务)没有正常退出?

C# 为什么在执行Application.Current.Shutdown时线程(任务)没有正常退出?,c#,wpf,multithreading,C#,Wpf,Multithreading,所以我正在创建任务并运行它们。 但是我看到,当我关机时——线程刚刚结束——我不知道处于哪种状态 当使用“任务”或“BackgroundWorker”时会发生这种情况,如果我使用的是线程,那么直到我的线程真正完成,应用程序才会结束 这意味着,我不知道如何正确地进行清理。 我应该在通知线程完成后调用关机吗?-这有点烦人,因为我希望应用程序尽快“停止所有UI” 谢谢 您根本不应该使用Application.Current.Shutdown。退出应用程序的正确方法是让用户关闭主窗口。使用Shutdown

所以我正在创建任务并运行它们。 但是我看到,当我关机时——线程刚刚结束——我不知道处于哪种状态

当使用“任务”或“BackgroundWorker”时会发生这种情况,如果我使用的是线程,那么直到我的线程真正完成,应用程序才会结束

这意味着,我不知道如何正确地进行清理。 我应该在通知线程完成后调用关机吗?-这有点烦人,因为我希望应用程序尽快“停止所有UI”

谢谢

您根本不应该使用
Application.Current.Shutdown
。退出应用程序的正确方法是让用户关闭主窗口。使用
Shutdown
是一个坏主意,原因有很多——例如,您将失去中止关机的能力(典型的情况是一个表单说“您有未保存的更改”)

编辑

OP明确表示他的应用程序没有主窗口,因此使用
application.Current.Shutdown
实际上是合适的。但是,只有在安全完成(或取消)所有关键的后台工作后才应调用它

默认情况下,
Task
BackgroundWorker
使用后台线程(实际上是线程池线程),这不会阻止应用程序退出。当进程退出时,所有后台线程都会死掉——没有异常,没有日志记录,没有终结。不要将后台线程用于关键任务。但是,请注意,另一种选择是线程根本不会退出,进程将继续运行-您必须自己处理所有后台任务的正常关闭


换句话说,当用户在上下文菜单中按退出时,取消任何正在运行的后台工作,等待其正确完成,并仅在所有工作成功完成后调用关机。

您可以使用取消令牌,查看您为什么要执行当前的关机操作。
Application.Current.Shutdown
?退出应用程序的正确方法是让用户关闭主窗口<默认情况下,code>Task和
BackgroundWorker
使用后台线程(实际上是线程池线程),这不会阻止应用程序退出。但是,请注意,另一种选择是线程根本不会退出,进程将继续运行-您必须自己处理所有后台任务的正常关闭。我确实使用取消令牌,但线程仍在退出。因为我是一个系统托盘应用程序,我没有“X”按钮,所以我实现了一个“退出”上下文菜单。在使用关机时,我如何实现替代方案?@ArielB您希望这些任务做什么?让主窗口等待它们完成?它们是创建的后台线程,而不是前台线程。嗯,我使用的是CancellationToken,我希望监视它并在任务中进行取消。解决方案不是使用任务,而是使用线程(前台)。但我认为我目前会继续使用后台线程,因为我是一个系统托盘应用程序,没有“X”按钮,所以我实现了一个“退出”上下文菜单。在使用关机时,我如何实现替代方案?@ArielB但您仍然有一个主窗口,即使它是隐藏的。因此,您仍然可以在该窗口上调用
Close
。不过,您必须手动处理所有线程的关闭。同样,如果你有一些不想被打断的背景工作,你必须手动处理。例如,显示一个对话框,上面写着“正在运行后台工作,等待或取消?”或类似的内容。在任何情况下,你都必须做簿记。我在WPF应用程序(App.XAML)下-我没有一个主窗口可以调用。这意味着在我想要完成的线程完成之前我不应该关闭-这有点烦人,因为UI仍然处于活动状态(我需要从系统托盘中删除上下文菜单)-听起来有点奇怪“某些应用程序的生存期可能不依赖于主窗口或最后一个窗口关闭的时间,也可能根本不依赖于窗口。对于这些场景,您需要将ShutdownMode属性设置为OnExplicitShutdown,这需要显式的Shutdown方法调用来停止应用程序。否则,应用程序将继续在后台运行。“明白。只有在我的重要线程完成后,我才会调用shutdown。谢谢!如果您愿意(对于其他人),应该编辑答案,因为关闭是WPF建议关闭应用程序的方式。