Висящий поток на Monitor.Wait после Application.Current.ShutDown()

У меня есть приложение WPF, которое раньше отключалось через Environment.Exit. Поскольку это вызвало проблемы с моими автоматическими тестами пользовательского интерфейса, я изменил существующее приложение на Application.Current.ShutDown.

Это работает нормально, за исключением того, что есть поток, ожидающий импульса (Monitor.Wait), который поддерживает работу процесса, поскольку он больше никогда не получает импульс.

Я думал, что исправить это будет несложно, но с точки, где мое приложение выходит (Application.Current.ShutDown), довольно сложно получить ссылку на объект, который содержит ожидающий поток (чтобы заставить его пульсировать, чтобы он мог выход).

Я попытался найти подходящий ответ в Google, но пока не очень повезло. Есть ли "легкий выход" из этого? Или мне уже начинать рефакторинг? :)

Некоторые фрагменты:

Тема создается так

workerThread = new Thread(Worker) { Name = logName, IsBackground = true};

В методе Worker вызывается Monitor.Wait

while ((action = GetNextTask(out task)) == ProductPreparationAction.None)
{
    Monitor.Wait(preparationTasks);
}

person bas    schedule 04.08.2014    source источник
comment
Вы ищете не тот поток для проблемы, тот, у которого для IsBackground установлено значение true, не может предотвратить завершение приложения. Используйте окно отладчика Debug + Windows + Threads, чтобы найти нарушителя спокойствия.   -  person Hans Passant    schedule 05.08.2014


Ответы (1)


Наплевать на мой комментарий. Начать рефакторинг :).

Прежде всего, должен быть способ, чтобы цикл while заканчивался до того, как приложение остановится. Возможно, вы сможете использовать и распространять метод CancellationToken вплоть до метода Worker.

Если вы хотите сохранить слабую связь, вы должны иметь возможность пульсировать, создавая событие в классе, который вызывает Application.Current.ShutDown, и подписываясь на него в классе, где находится метод Worker (и вызывая Pulse в обработчике событий).

Если вы сделаете это, вы сможете сохранить CancellationToken в этом классе и пометить его при получении события.

Это событие должно быть вызвано до вызова Application.Current.ShutDown.

person Marcel N.    schedule 04.08.2014