Могу ли я определить, когда фоновый поток завершается приложением при закрытии приложения?

Я использую поток на C #, в котором для свойства IsBackground установлено значение true. Поток выполняет некоторый код в цикле, пока приложение не закроется. Когда приложение закрывается, поток также перестает выполняться (потому что я установил IsBackground = true).

Как приложение убивает поток? Кажется, что он не делает этого, вызывая прерывание, потому что я не получаю ThreadAbortException. Это происходит за кадром? Я хотел бы сделать откат в моем блоке finally цикла.

Я знаю, что могу просто вызвать прерывание в потоке, но я хочу знать, как приложение закрывает мой фоновый поток, и могу ли я отреагировать на него изнутри потока. Я знаю, что могу подписаться на событие Application.ApplicationExit, но я запускаю этот код как в сервисе, так и в winform, и я бы предпочел перехватить исключение внутри цикла, чтобы я мог выполнить откат в инструкции finally.


person Ben Adams    schedule 13.06.2012    source источник
comment
Вы можете сделать его потоком переднего плана и создать «глобальный» сценарий завершения работы приложения, который вручную закрывает поток.   -  person CodingBarfield    schedule 13.06.2012
comment
Вы видели событие AppDomain.ProcessExit?   -  person Botz3000    schedule 13.06.2012
comment
Итак, вы оба говорите, что это происходит за кулисами, и я не могу на это отреагировать, кроме как создавать такие нестандартные решения?   -  person Ben Adams    schedule 13.06.2012


Ответы (2)


Кажется, он не делает этого, вызывая прерывание, потому что я не получаю ThreadAbortException

Это так, у CLR есть два способа прервать поток. «Обычным» способом, вызываемым через Thread.Abort (), поток может увидеть исключение ThreadAbortException. Но есть и грубое прерывание, работает точно так же. Но без TAE и без выполнения блоков finally. Вы не можете этого наблюдать.

person Hans Passant    schedule 13.06.2012
comment
Ага .. Спасибо, что разобрались. Я не смог найти никакой документации по этому поводу - person Ben Adams; 13.06.2012
comment
Это ошибка в MSDN? msdn.microsoft.com/en-us/library/ Когда среда CLR останавливает фоновые потоки после завершения всех потоков переднего плана в управляемом исполняемом файле, Thread.Abort не используется. Следовательно, вы не можете использовать ThreadAbortException, чтобы определить, когда фоновые потоки завершаются CLR. - person Eldar; 06.02.2014
comment
Я не вижу разницы между этой статьей MSDN и этим ответом. Грубые прерывания могут быть вызваны кодом приложения, но вам понадобятся AppDomain.Unload или Environment.Exit, обычно это не те методы, о которых кто-то сначала думает как о способе прерывания потока :) - person Hans Passant; 06.02.2014

Started thread переходит в состояние Running (т.е. начинает выполнение), когда операционная система назначает процессор для thread. Когда запущенный поток впервые получает процессор и становится запущенным потоком, поток выполняет свой ThreadStart delegate, который определяет действия, которые поток будет выполнять в течение своего жизненного цикла. Когда программа создает новый поток, программа указывает ThreadStart delegate потока в качестве аргумента для конструктора потока.

Выполняющийся поток переходит в состояние Stopped (or Dead), когда его ThreadStart delegate завершается. В вашем случае ваш основной поток завершается. Итак, ваш ThreadStart delegate объект не остается в памяти. Когда нет ссылок на объект потока, сборщик мусора может удалить объект потока из памяти.

person Talha    schedule 13.06.2012
comment
Спасибо за хорошее объяснение этого. В итоге я использовал событие AppDomain.ProcessExit, как предлагал Botz3000. Затем я могу вызвать thread.Abort () при возникновении этого события. Вроде хорошо работает. - person Ben Adams; 13.06.2012
comment
Это неверный ответ. Заброшенный фоновый поток не прерывается сборщиком мусора. Он принудительно прерывается средой выполнения независимо от того, какие сильные ссылки у вас есть на объект управляемого потока. См. Объяснение в ответе Ганса. - person Josh; 13.06.2012
comment
@JoshEinstein: Может быть, вы правы, но Ханс не объяснил, как CLR аварийно прерывает поток .... Можете ли вы объяснить? - person Talha; 13.06.2012
comment
Он убивает его (предположительно, с использованием функции Windows, такой как ExitThread) вне вашего контроля, без запуска вашего управляемого кода. Если вам необходимо обеспечить выполнение кода после завершения потока, вы должны сигнализировать фоновым потокам о завершении перед выходом из основного потока. - person Josh; 13.06.2012