Процесс приложения не завершается после закрытия основной формы - с использованием ApplicationContext

У меня есть приложение Windows Forms, после закрытия основной формы процесс не завершается.

Я использую ApplicationContext, потому что у меня есть докладчик, который генерирует мою основную форму.

Application.Run(new ApplicationContext(Instance.InitPresentationManager()));

У меня есть методы DestroyHandle и OnHandleDestroyed, переопределенные для целей отладки. Там я вижу, что вызывается DestroyHandle, но не OnHandleDestroyed! Это причина, по которой мой процесс все еще работает, потому что ApplicationContext внутренне регистрируется для события HandleDestroyed.

В методах DestroyHandle свойство HandleCreated даже изменяется с true на false. Я даже переопределил WndProc и вижу, что сообщение «2» не получено (оно вызывает WmDestroy в классе Control и запускает событие OnHandleDestroyed).

Как это возможно?

Примечания:

  • OnHandleDestroy вызывается только в начале, когда RecreatingHandle имеет значение true
  • При подключении к процессу и прерывании всех потоков основной поток все еще находится в методе Application.Run.
  • Я даже подключился к профилировщику памяти, который сообщает мне, что больше нет живых экземпляров моей основной формы
  • Application.Exit в основной форме Dispose работает и устраняет симптомы, но не решает саму проблему.
  • После перезагрузки компьютера он некоторое время работает нормально, но со временем проблема возникает снова.
  • Win 7 64 бит, VS 2010, .net 4.0

person toATwork    schedule 22.01.2014    source источник


Ответы (1)


Проблема в том, что закрытие формы не обязательно означает, что приложение должно завершить то, что в настоящее время делает. (подумайте о том, чтобы писать файлы журналов, аккуратно закрывать потоки связи и т. д.).

У потока есть свойство IsBackground (см. http://msdn.microsoft.com/en-us/library/system.threading.thread.isbackground(v=vs.110).aspx), что фактически означает, разрешено ли это убит в середине операции. Проверьте все текущие потоки, чтобы убедиться, что они работают с соответствующим маркером фонового потока.

Попробуйте использовать метод удаления в контексте приложения. Это вполне приемлемый шаблон и способ сказать, что я покончил с этим, идите и избавьтесь от него, чтобы позволить долго работающим потокам закончить работу.

person Immortal Blue    schedule 22.01.2014
comment
Использование Application.Run обязательно означает, что при закрытии формы приложение должно выйти, см. MSDN: msdn.microsoft.com/en-us/library/ms157902%28v=vs.100%29.aspx - person toATwork; 22.01.2014
comment
Завершить! = Выход. Прекратить - это остановить то, что вы делаете прямо сейчас. Выход - это готово, когда вы закончите - person Immortal Blue; 22.01.2014
comment
Об этом я и говорю в своем вопросе. Основной поток все еще работает. Поэтому приложение не выходит. Что еще хуже, кажется, что в документации MSDN есть ошибка, они заявляют, что Application.Run ожидает события закрытия формы. Я проверил источник, который они ждут, когда дескриптор уничтожен, но в моем случае это не срабатывает. - person toATwork; 22.01.2014
comment
Какая обработка происходит в вашей основной форме? вы начинаете какие-нибудь темы? Можете ли вы предоставить простой пример исходного кода? - person Immortal Blue; 22.01.2014
comment
Основная форма более-менее тупая. Просто графический интерфейс и регистрация обработчиков событий на кнопках и так далее. Это причина для всей реализации презентатора, чтобы держать бизнес-логику подальше от элементов управления и форм графического интерфейса. - person toATwork; 22.01.2014