Нить не прерывается при закрытии приложения
У меня есть приложение, которое выполняет некоторую фоновую задачу (прослушивание и чтение в сети) в отдельном Thread
. Однако, похоже, что нить не прерывается/отменяется, когда я закрываю приложение (нажмите кнопку "x" на панели заголовка).
Это потому, что основная программа Thread - while(true) {...}
?
Какое здесь решение? Я искал флаг "прерывания" для потока как условие для цикла "while", но не нашел.
Ответы
Ответ 1
Самый простой способ - установить свойство IsBackground потока в true. Это предотвратит сохранение приложения. Приложение завершается, когда все нефонические потоки завершаются.
Более контролируемый способ остановить поток - отправить сообщение, чтобы оно было закрыто, и убедитесь, что оно завершено, прежде чем разрешить основной поток.
Метод, который я бы не рекомендовал, - это вызвать Thread.Abort
. У этого есть ряд проблем, один из которых заключается в том, что не гарантируется прекращение потока. Из документации:
Вызов этого метода обычно завершает поток.
Акцент на мой.
Ответ 2
Вы всегда можете заставить проблему:
class Program
{
public static void Main()
{
// ... do stuff
Environment.Exit(Environment.ExitCode);
}
}
Лучший подход заключается в том, чтобы установить свойство Thread.IsBackground в значение true, как уже упоминалось Mark.
Ответ 3
Вы можете улучшить цикл while (true) до
void DoWork() {
while(!ShouldIQuitManualResetEvent.WaitOne(0)) {
// do something
}
IDidQuitManualResetEvent.Set()
}
Немного более изящный, короткий от имен идентификаторов.
Ответ 4
Ну, а не while(true)
, может быть, вам нужно:
while(appIsRunning)
{
}
И, при закрытии для вашей формы,
appIsRunning = false;
thread.Join(2000);
где последняя строка предназначена только для того, чтобы убедиться, что вы дождались завершения финиша. Есть много других способов заставить конец потоку, но проблема только в этом: вы не хотите заставлять вещи, вы хотите, чтобы они происходили как можно более естественно.
После объединения вы можете проверить статус потока, чтобы узнать, завершено ли оно. Если это не так, , а затем (и только потом) заставит закончить с прерыванием и может уведомить вашего пользователя (или записать запись журнала), что что-то не закончилось так, как должно быть.
Ответ 5
Вы можете начать свой поток как:
ThreadPool.QueueUserWorkItem(DoStuff, input)
И он автоматически прекратится при закрытии приложения.