Как я могу заставить все потоки программы завершаться при закрытии программы?

#c# #multithreading

#c# #многопоточность

Вопрос:

Как я могу гарантировать, что все потоки программы прервутся после того, как я закрою главное окно?

Комментарии:

1. Установлены ли потоки в качестве фоновых потоков?

2. Избегайте запуска и забывания потоков. Environment.Exit() — это решение для вопросов и ответов.

Ответ №1:

Вы можете установить для свойства «IsBackground» значение true. Среда CLR закрывает все фоновые потоки при выходе из приложения.

Ответ №2:

  • Если вы хорошо спроектировали потоки, у вас должен быть механизм для их закрытия — например, используйте a ManualResetEvent , чтобы сигнализировать им о закрытии
  • Вы можете выполнять поток.Присоединиться, чтобы дождаться, пока они не закроются, или поток.Прервать, чтобы они прервались неприятным образом
  • Если они являются фоновыми потоками, они закроются, когда приложение завершит работу

Смотрите также: http://msdn.microsoft.com/en-us/library/7a2f3ay4 (v= против 80).aspx

Комментарии:

1. Я добавлю стандартный комментарий — никогда не используйте прерывание (выполните поиск здесь в S / O, чтобы увидеть все подробности о том, почему это очень плохая идея).

2. Хотя прочитайте, почему, потому что в большинстве случаев это вполне приемлемый компромисс. Боюсь, что «Никогда не используйте прерывание» неверно.

3. Справедливое замечание. Как насчет того, чтобы не делать этого, если вы не понимаете аргументов против и у вас нет альтернативы.

Ответ №3:

Попробуйте

 Application.ExitThread();
Environment.Exit(0);
  

или

 Dispatcher.CurrentDispatcher.Thread.Abort();
  

Ответ №4:

Соберите их где-нибудь, например

 static public List<Thread> AllThreads;
  

и используйте эту коллекцию для .Abort() них, один за другим.

Это ТРУДНЫЙ и НЕПРАВИЛЬНЫЙ путь. Лучше было бы каким-то образом дать им сигнал остановиться, а затем .Join() один за другим.

Комментарии:

1. Вы имеете в виду .Abort() ? .Terminate не существует

2. Кроме того, если у вас есть список, почему бы и нет AllThreads.ForEach(t => t.Abort()); ?

3. @KierenJohnstone когда я сказал завершить их один за другим, это именно то, что я имел в виду. Лямбда или нет, вы завершаете их один за другим.

4. Я просто подумал, что реальный пример был бы идеальным, просто предложение 🙂

5. Да, это круто. Мне нравятся лямбды, но их почему-то сложно отлаживать. В любом случае, OP должен использовать. Abort() только если он ленив и не имеет других средств остановки потоков.

Ответ №5:

Установите IsBackground для свойства значение true и добавьте следующие строки:

 AppDomain.CurrentDomain.ProcessExit  = CloseMe; // for the main process
AppDomain.CurrentDomain.DomainUnload  = CloseMe; // for ApplicationDomains
  

Пусть CloseMe метод установит флаг, который проверяется в основном цикле потока.

Ответ №6:

Позволяя программе фактически закрыться, т. Е.. не вводите намеренно какой-либо код, который заставляет поток, запускающий главное окно, ждать каких-либо других потоков. Поток, который запускает главное окно, будет свободен для ExitProcess(), и тогда ОС прервет все другие потоки в вашем процессе, независимо от того, что они делают.

Rgds, Мартин

Комментарии:

1. По умолчанию в .NET потоки, которые не являются фоновыми, будут означать, что приложение не будет просто «закрываться». Если вы вызываете ExitProcess (который называется Environment . Выход в . ЧИСТЫЙ мир), это сработало бы