Использует ли Thread.Abort () и обрабатывает ли исключение ThreadAbortException в безопасной практике .NET?
TL; версия DR: нет, не.
Как правило, вы в безопасности, когда все инварианты типов (независимо от того, указаны они явно или нет) действительно верны. Однако многие методы будут ломать эти инварианты во время работы, только чтобы достичь нового состояния, когда они снова верны в конце. Если поток находится в режиме ожидания с сохраненными инвариантами, все будет в порядке, но в этом случае лучше использовать что-то вроде события, чтобы изящно сигнализировать о выходе потока (т. Е. Вам не нужно прерывать работу).
Исключение внеполосного 1 , которое выдается в потоке в таких инвариантах-не-истина, т.е. недействительно, состояние, где начинаются проблемы. Эти проблемы включают, но не ограничиваются, взаимно несовместимые значения полей и свойств (структуры данных в недопустимом состоянии), блокировки не завершены, а события, представляющие «произошли изменения», не сработали.
Во многих случаях с этим можно разобраться в коде очистки (например, блок finally
), , но , а затем рассмотрите, что произойдет, если во время этой очистки возникнет исключение вне диапазона. код? Это приводит к очистке кода для очистки кода. Но тогда этот код самочувствителен, так что вам нужен код очистки для кода очистки кода очистки & hellip; это никогда не кончается!
Существуют решения, но их нелегко спроектировать (и, как правило, они влияют на весь ваш дизайн), и еще сложнее протестировать - как воссоздать все дела (например, комбинаторный взрыв). Два возможных маршрута:
Работа с копиями состояния, обновление копий, а затем атомная замена текущего состояния на новое. Если есть внеполосное исключение, то сохраняется исходное состояние (и финализаторы могут очистить временное состояние).
Это похоже на функцию транзакций базы данных (хотя СУБД работают с блокировками и файлами журналов транзакций).
Это также похоже на подходы к достижению «гарантии строгих исключений», разработанные в сообществе C ++ в ответ на бумажный опрос, могут ли исключения быть когда-либо безопасными (C ++, конечно, не имеет GC / финализатор очередь для очистки выброшенных объектов). См. Herb Sutters «Гуру недели № 8: ВЫЗОВ ВЫПУСК: Исключительная безопасность» для решения.
На практике этого трудно достичь, если ваше состояние не может быть заключено в одну ссылку.
Посмотрите на «Области ограниченного выполнения» , но не ограничения на то, что вы можете сделать в этих случаях. (В журнале MSDN была вступительная статья (введение в предмет, а не вступительный уровень), начиная с бета-версии .NET 2 2 ).
На практике, если вам нужно сделать это, использование подхода № 2 для управления изменением состояния под № 1, вероятно, является лучшим подходом, но получить его правильно, а затем проверить, что это правильно (и правильность поддерживается), жесткий .
Резюме: это немного похоже на оптимизацию: правило 1: не делайте этого; Правило 2 (только для экспертов): не делайте этого, если у вас нет другого выбора.
1 A ThreadAbortException
не единственное такое исключение.
2 Так что детали, возможно, изменились.