In system we have methods that lock an object by specific params.
As implementation, we have LockManager with Enter method that receives a key for a lock, check if lock object exists in internal dictionary, if not, it creates it and then locks.
What I want to do, is to set “X expected time” for specific lock, and if an object was locked for more that X time, I want to write a message to our log.
Below is a source code for my lock manager:
public class MyLockManager<T>
{
protected Dictionary<T, object> LockDictionary { get; private set; }
public MyLockManager()
{
LockDictionary = new Dictionary<T, object>();
}
/// <summary>
/// Enters a lock on the key.
/// </summary>
/// <param name="key">The key to lock.</param>
public virtual void Enter(T key)
{
if (!LockDictionary.ContainsKey(key))
{
lock (LockDictionary)
{
if (!LockDictionary.ContainsKey(key))
{
LockDictionary.Add(key, new object());
}
}
}
object lockObj = LockDictionary[key];
Monitor.Enter(lockObj);
}
/// <summary>
/// Releases the lock on the key.
/// </summary>
/// <param name="key">The key to release.</param>
public virtual void Exit(T key)
{
if (LockDictionary.ContainsKey(key))
{
Monitor.Exit(LockDictionary[key]);
}
}
}
Now I want to add an additional method, lets say LockTimoutHandler(T key) that will be called, if object for specific key was locked for more than X time.
In order to do it, I want to add some logic to “Enter” and “Exit” methods. When Enter called, something will be somehow registered to run the LockTimoutHandler in X time, and when “Exit” called, that something will be somehow unregistered.
My question is what I can use instead of that something? How I can schedule the method to run in X time and if Exit occurred before, so remove the schedule. It must be very fast, since performance is very important in our case. I know about Timer object…it can execute method in delayed manner, but is it’s performance good enough? What additional options I have to achieve that?
NOTE: Just to be clear, I am not talking about TryEnter. I am not trying to catch the case when the object can not be locked for specific amount of time, I want to catch objects that already locked for too much time.
Thanks!
We had a similar rquirement and solved it this way:
This will keep as many timers around as necessary, but no more and will incur the cost of allocation/deallocation only once. Since you can’t change the timer’s state object, you need to change its contents.