Что не так с использованием Thread.Abort () - PullRequest
61 голосов
/ 13 октября 2009

Так что я знаю, что вы не должны использовать

Thread.Abort()

Но мне никогда не давали хорошего объяснения. Есть ли потеря производительности или какая-то скрытая ошибка?

Я знаю, что вы не можете игнорировать / глотать исключение ThreadAbortException (что имеет смысл)

Ответы [ 7 ]

78 голосов
/ 13 октября 2009

В дополнение ко всем другим хорошим ответам здесь, позвольте мне добавить, что нет никакой гарантии, что вызов Thread.Abort фактически прервет рассматриваемый поток, когда-либо. Возможно (хотя и не особенно легко) «затвердеть» нить от прерывания. Например, если вы прерываете поток, потому что считаете, что он выполняет враждебный код, тогда враждебный код может противостоять самому уничтожению.

Если у вас есть длительная операция с кодом, которым вы не владеете, который должен быть аккуратно удален, правильный способ сделать это - поместить этот код в собственный процесс , а не в его собственный нить. (И предпочтительно в домене приложений с высоким уровнем безопасности в этом процессе.) Затем вы можете просто убить процесс.

Короче говоря, Thread.Abort в лучшем случае указывает на плохой дизайн, возможно, ненадежный и чрезвычайно опасный. Следует избегать любой ценой; единственный раз, когда вам стоит подумать об прерывании потока, это какой-то код «аварийного отключения», когда вы пытаетесь уничтожить домен приложения как можно более аккуратно.

17 голосов
/ 13 октября 2009

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

Поток мог взять блокировку и быть в процессе изменения какого-либо общего состояния, и Thread.Abort отменит блокировку и оставит общее состояние поврежденным.

13 голосов
/ 13 октября 2009

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

Monitor.Enter(obj);
// some code - if exception is raised here, then the lock isn't released
Monitor.Exit(obj)

IDisposable someCriticalResource = GetResource();
// some code - if exception is raised here, then the object isn't disposed
someCriticalResource.Dispose();

Кроме того, если вы работаете со многими людьми в команде, если у вас нет хороших обзоров кода, вы не можете гарантировать качество кода, с которым будете работать. Следовательно, лучше проповедовать о том, что «нет Thread.Abort ()», чем заставить людей помнить, что они должны писать код, устойчивый к исключениям, происходящим в любом месте внутри этого кода.

7 голосов
/ 13 октября 2009

Короче. Любой объект IDisposable не может быть утилизирован. Любой заблокированный объект не может быть разблокирован. Все, что должно быть выполнено на 100%, никогда не будет выполнено.

4 голосов
/ 13 октября 2009

Когда вы вызываете Thread.Abort () в другом потоке, в поток этого потока вводится исключение ThreadAbortException. Если вам повезет, код будет хорошо обработан и прервется в четко определенном состоянии. Проблема в том, что у вас нет возможности выяснить, повезет ли вам в каждом случае, поэтому, если вы предпочитаете безопасный, а не сожалеющий вызов Thread.Abort в других потоках, не очень хорошая идея.

2 голосов
/ 13 октября 2009

Тема. Аборт останавливает вашу тему неконтролируемым образом. thread.Abort сгенерирует исключение, которое приведет к немедленной остановке вашего потока.

Что не так с этим: в большинстве случаев вы хотите аккуратно остановить выполняемую вами операцию. Например, если вы выполняете операцию ACID, вы можете завершить текущую операцию до завершения потока, чтобы ваша система оставалась в стабильном состоянии.

1 голос
/ 13 октября 2009

Thread.Abort вызывает исключение в целевом потоке. Тем временем целевой поток может выполнять некоторые критические операции, и возникновение исключения может нарушить состояние вашего приложения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...