От this page:
Каждый замок приобретение может вызвать исключение. Будьте готовы к этому.
Большинство шлюзов лениво выделяют событие, если обнаружение блокировки встречает конфликт, включая мониторы CLR. Это распределение может завершиться неудачно при низких ресурсных условиях, в результате чего OOM отправляются из входа в блокировку. (Обратите внимание, что типичная блокировка блокировки не может прерываться с помощью OOM, что позволяет использовать ее в некоторых сценариях с ограниченными ресурсами, таких как внутри CER.) Аналогично, такой сервер, как SQL Server, может выполнять обнаружение блокировки и даже блокировать эти блокировки с помощью генерируя исключения, которые исходят из инструкции Enter, проявляющиеся как System.Runtime.InteropServices.COMException.
Часто не так много, что можно сделать в ответ на такое исключение. Но надежный и безопасный код, который должен иметь дело с отказом, должен учитывать этот случай. Нам бы хотелось, чтобы это было так, что блокирование хостов может быть воспринято разумно, но большинство библиотечных кодов не могут разумно расслабиться в безопасном месте в стеке, чтобы он мог отступить и повторить операцию. В типичном стеке слишком много межбиблиотечного смешения. Вот почему учетные записи на основе тайм-аута с TryEnter обычно представляют собой плохую идею для предотвращения тупиковой ситуации.
Так как вы можете читать, кажется, что в условиях ограниченного ресурса мы можем получить исключения, вызванные методом Enter, который блокирует (o), используя внутренне.
Так что, может быть, ваше решение - это что-то вроде спина-ожидания?
{
uint iters = 0;
while (!cond) {
if ((++iters % 50) == 0) {
// Every so often we sleep with a 1ms timeout (see #30 for justification).
Thread.Sleep(1);
} else if (Environment.ProcessorCount == 1) {
// On a single-CPU machine we yield the thread.
Thread.Sleep(0);
} else {
// Issue YIELD instructions to let the other hardware thread move.
Thread.SpinWait(25);
}
}
}
Где Cond может быть какой-то
private volatile int cond = 0
используется, например, с Interlocked.CompareExchange, где вы меняете, например. Thread.Current.ManagedThreadID или что-то еще отличное от нуля?
Какое исключение? Можете ли вы предоставить стек вызовов? – mfeingold
Вам действительно нужно добавить дополнительную информацию и объяснить, как именно вы «вызываете из неуправляемого». –