Is there a "try to lock, skip if timed out" operation in C#?
I need to try to lock on an object, and if its already locked just continue (after time out, or without it).
The C# lock statement is blocking.
Solution 1:
Ed's got the right function for you. Just don't forget to call Monitor.Exit()
. You should use a try-finally
block to guarantee proper cleanup.
if (Monitor.TryEnter(someObject))
{
try
{
// use object
}
finally
{
Monitor.Exit(someObject);
}
}
Solution 2:
I believe that you can use Monitor.TryEnter()
.
The lock statement just translates to a Monitor.Enter()
call and a try catch
block.
Solution 3:
I had the same problem, I ended up creating a class TryLock
that implements IDisposable and then uses the using
statement to control the scope of the lock:
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;
}
}
}
And then use the following syntax to lock:
var obj = new object();
using (var tryLock = new TryLock(obj))
{
if (tryLock.HasLock)
{
Console.WriteLine("Lock acquired..");
}
}
Solution 4:
Consider using AutoResetEvent and its method WaitOne with a timeout input.
static AutoResetEvent autoEvent = new AutoResetEvent(true);
if(autoEvent.WaitOne(0))
{
//start critical section
Console.WriteLine("no other thread here, do your job");
Thread.Sleep(5000);
//end critical section
autoEvent.Set();
}
else
{
Console.WriteLine("A thread working already at this time.");
}
See https://msdn.microsoft.com/en-us/library/cc189907(v=vs.110).aspx https://msdn.microsoft.com/en-us/library/system.threading.autoresetevent(v=vs.110).aspx and https://msdn.microsoft.com/en-us/library/cc190477(v=vs.110).aspx