public static void Lock(ref int lockIndex) { for (;;) { if (System.Threading.Interlocked.Exchange(ref lockIndex, 1) == 0) { break; } } } public static void Unlock(ref int lockIndex) { System.Threading.Interlocked.Exchange(ref lockIndex, 0); }
Мы заводим int поле и используем его в качестве идентификатора для операции блокирования. Другими словами, пока не будет вызван Unlock, второй поток не пройдет через Lock.
Из минусов такого подхода - если ваш код между этими вызовами упадет по исключению, то все ожидающие потоки повиснут. Для этого я написал дополнение, которое выходит из цикла с ошибкой, если мы ждем слишком долго.
Как я писал выше в одном из постов, лучше вообще избегать блокировки и Interlocked, но в редких случаях без них не обойтись.