ReaderWriterLockSlim устойчив к ThreadAbortException?

Я хотел бы проверить, является ли следующий код устойчивым к ThreadAbortException и не приведет к блокировке сирот. Если это не так, каков наилучший способ избежать блокировки сирот здесь?

ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();

public void DoStaff()
{
  _lock.EnterWriteLock();
  //Is this place where ThreadAbotException can corrupt my code, or is there JIT optimalization which prevent this from happening??? 
  try
  {
    ...
  }
  finally
  {
    _lock.ExitWriteLock();
  }
}

По следующей ссылке http://chabster.blogspot.cz/2013/07/a-story-of-orphaned-readerwriterlockslim.html, есть (или, по крайней мере, был) возможный способ создания бесхозных блокировок, но у меня был пример Код на некоторое время без удачи.

Я использую.NET 4.0

Есть ли разница между поведением в Debug и Release?

2 ответа

Решение

Да, ThreadAbortException может произойти там, и в этом случае try не будет введен, и поэтому вы никогда не выйдете из блокировки записи.

Нет хорошего общего решения проблемы. Вот почему Эрик Липперт (среди прочих) говорит, что блокировки и исключения не смешиваются.

Вы спрашиваете конкретно о ThreadAbortExceptionчто заставляет меня поверить, что вы собираетесь использовать Thread.Abort для какого-то управления потоками в вашем приложении. Я призываю вас пересмотреть. Если вы хотите отменить ваши темы, вы должны использовать Cancellation или что-то подобное. С помощью Thread.Abort в любых других случаях, кроме самых ужасных, это ужасно плохая идея. Это, конечно, не должно быть частью общего дизайна вашей программы.

Для того чтобы код, который использует блокирующий примитив, был устойчивым перед лицом прерываний потока, необходимо, чтобы каждый запрос на получение блокировки и снятие блокировки проходил или выполнялся через общий ресурс, которому можно дать "право собственности" на замок. В зависимости от конструкции API блокировки токен может быть объектом определенного типа, произвольным Objectили переменная, переданная как ref параметр. Однако обязательно, чтобы токен был создан и сохранен каким-либо образом до того, как будет получена блокировка, чтобы в случае создания токена, но при сбое хранилища токен можно было без труда покинуть. К сожалению, хотя блокировки монитора добавили (в.NET 4.0) перегрузки Monitor.Enter а также Monitor.TryEnter которые используют ref bool в качестве знака я не знаю эквивалента замков читателя-писателя.

Если кто-то хочет, чтобы функциональность блокировки читателя-писателя была безопасной, я бы предложил, чтобы ему был нужен класс, который был разработан для этого; он должен отслеживать, какие потоки имеют доступ для чтения или записи, и вместо того, чтобы полагаться на потоки для снятия блокировок, он должен, ожидая снятия блокировки, убедиться, что поток, удерживающий его, все еще жив. Если поток умирает, удерживая доступ на чтение, он должен быть освобожден. Если поток умирает, удерживая право доступа, любые ожидающие или будущие попытки получить блокировку должны вызвать немедленное исключение.

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

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

Другие вопросы по тегам