Нить не прерывается при закрытии приложения

У меня есть приложение, которое выполняет некоторую фоновую задачу (прослушивание и чтение в сети) в отдельном 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)

И он автоматически прекратится при закрытии приложения.