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