#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 . Выход в . ЧИСТЫЙ мир), это сработало бы