Мне нужно попытаться заблокировать объект, и если он уже заблокирован, просто продолжайте (после таймаута или без него).
Оператор блокировки С# блокирует.
Мне нужно попытаться заблокировать объект, и если он уже заблокирован, просто продолжайте (после таймаута или без него).
Оператор блокировки С# блокирует.
Я считаю, что вы можете использовать Monitor.TryEnter()
.
Оператор блокировки просто преобразуется в вызов Monitor.Enter()
и блок try catch
.
Эд получил правильную функцию для вас. Просто не забудьте позвонить Monitor.Exit()
. Вы должны использовать блок try-finally
, чтобы гарантировать правильную очистку.
if (Monitor.TryEnter(someObject))
{
try
{
// use object
}
finally
{
Monitor.Exit(someObject);
}
}
У меня была такая же проблема, я закончил создание класса TryLock
, который реализует IDisposable, а затем использует оператор using
для управления областью блокировки:
public class TryLock : IDisposable
{
private object locked;
public bool HasLock { get; private set; }
public TryLock(object obj)
{
if (Monitor.TryEnter(obj))
{
HasLock = true;
locked = obj;
}
}
public void Dispose()
{
if (HasLock)
{
Monitor.Exit(locked);
locked = null;
HasLock = false;
}
}
}
И затем используйте следующий синтаксис для блокировки:
var obj = new object();
using (var tryLock = new TryLock(obj))
{
if (tryLock.HasLock)
{
Console.WriteLine("Lock acquired..");
}
}
Вы, вероятно, узнаете это сейчас, когда другие указали вам в правильном направлении, но TryEnter также может принять параметр тайм-аута.
Джефф Рихтер "CLR Via С#" - отличная книга о деталях внутренних свойств CLR, если вы попадаете в более сложные вещи.
Рассмотрим использование AutoResetEvent и его метод WaitOne с таймаутом.
См. https://msdn.microsoft.com/en-us/library/system.threading.autoresetevent(v=vs.110).aspx и https://msdn.microsoft.com/en-us/library/cc190477(v=vs.110).aspx