4 ответов:
Во-первых, ни одна из этих конструкций не является хорошей синхронизацией потоков.
Во-Первых, Поток.Abort говорит: "мне все равно, что вы делаете, просто прекратите это делать и оставьте все как есть прямо сейчас". Это в основном программный способ сказать:"Эй, забей". Если ваш поток имеет открытые файлы, эти файлы будут оставаться открытыми до тех пор, пока сборщик мусора не доберется до завершения ваших объектов.
Поток.Аборт должен использоваться только когда-либо, и даже тогда, вероятно, нет, в случай, когда домен приложения, в котором работает поток, разрывается, предпочтительно только тогда, когда процесс завершается.
Во-Вторых, Поток.Interrupt - довольно странный зверь. Он в основном говорит: "мне все равно, чего ты ждешь, перестань ждать этого". Странная вещь здесь заключается в том, что если поток в данный момент ничего не ждет, то вместо этого "мне все равно, чего вы собираетесь ждать дальше, но когда вы это сделаете, прекратите ждать его немедленно".
Оба эти признака указывают на то, что вы навязываете свою волю потоку, который не был создан для того, чтобы говорить такие вещи.
Чтобы прервать поток должным образом, поток должен периодически проверять какой-либо флаг, будь то простая изменчивая булева переменная или объект события. Если флаг говорит "Теперь вы должны завершить", поток должен завершить себя, возвращаясь из методов упорядоченным образом.
Чтобы правильно разбудить нить, Нить должна, в местах, где он должен ждать объекты синхронизации, включая объект" пожалуйста, прекратите ждать", который он также ждет. Таким образом, в основном это будет либо для объекта, который ему нужен, становится сигналом, либо для объекта "пожалуйста, перестаньте ждать" становится сигналом, определите, какой из них сделал, и сделайте правильную вещь.
Так вместо нити.Аборт и нить.Прерывание, вы должны писать свои потоки, используя обычные объекты синхронизации, такие как события, мьютексы, семафоры и т. д.
По той же причине, нить.Приостановить и поток.Резюме следует оставить в покое, и они также были устаревшими в более поздних версиях. NET.
Если вы не вызываете
AbortилиInterruptв текущем исполняемом потоке (как ASP.NET делает, чтобы прервать запрос резко, например) вы в принципе не можете вызвать их потокобезопасным способом.Используйте
WaitHandleилиMonitor.Wait/Pulseждать в бодрствующем состоянии. Вы должны прерывать другие потоки только в том случае, если вы разрушаете приложение, в основном - так как в противном случае вы можете оказаться в неизвестном состоянии.Смотрите мою статью о изящном завершении потока Для примера того, как чтобы сделать это красиво.
Поток.Abort() вызывает ThreadAbortException в целевом потоке. Это намерение, как правило, заставить поток завершиться. Это не рекомендуется для остановки обработки потока.
Поток.Функция Interrupt() прерывает поток, находящийся в состоянии WaitSleepJoin, по сути блокируя такой ресурс, как WaitHandle. Это позволяет вызывающему объекту разблокировать поток.
Ни один из них не является действительно "потокобезопасным" - в том смысле, что они специально предназначены для воздействия на поведение потоков таким образом, что его трудно предсказать.
Обычно рекомендуется использовать объекты синхронизации (например, WaitHandles или семафоры), чтобы обеспечить безопасную синхронизацию потоков друг с другом.
Разница между Abort и Interrupt заключается в том, что, хотя они оба вызовут исключение (ThreadAbortException и ThreadInterruptException), вызов Abort перерастет исключение в конце блока catch и обязательно завершит запущенный поток.
Comments