I have a situation where, for testing, I only want my timer method (FooMethod) to run one at a time. In the example below, FooMethod is passed as the delegate to a timer. There are many concrete instances of this class. I thought that by making _locker static, only one instance of FooMethod() would process at a time. But when I run the app, multiple threads are getting past the TryEnter() line at a time.
This is how I’m adding each class to a new timer. This is done, in a loop, for each foo instance:
_timers.Add(new Timer(foo.FooMethod, null, 0, 10000));
And this is the class that has that method:
public class Foo<T>
{
private static readonly object _locker = new object();
public void FooMethod(object stateInfo)
{
// Don't let threads back up; just get out
if (!Monitor.TryEnter(_locker)) { return; }
try
{
// Logic here
}
finally
{
Monitor.Exit(_locker);
}
}
}
Note: Normally, _locker isn’t static; I don’t want the same thread entering the method before it got a chance to complete. I changed it to static here for testing.
My first thought is that maybe this isn’t working because the class is generic? And that each concrete class is actually its own class and they don’t share the _locker variable? Is that true? If that’s true how should I have the concrete classes share a _locker variable? Do I need to add a static _locker variable to some other class to which the Foos have access?
Yes.
Each closed
Foo<T>type, with differentTarguments, has its own static _locker object. You could make Foo inherit from a base class, and put the static object there. Then, all the types would use the same instance.