Monitor.TryEnter with Generic Class

Bob*_*orn 7 c# multithreading locking

我有一种情况,为了测试,我只希望我的计时器方法(FooMethod)一次运行一个.在下面的示例中,FooMethod作为委托传递给计时器.这个类有很多具体的例子.我认为通过使_locker静态,只有一个FooMethod()实例会一次处理.但是当我运行应用程序时,多个线程一次超过TryEnter()行.

这就是我将每个类添加到新计时器的方法.这是在一个循环中为每个foo实例完成的:

_timers.Add(new Timer(foo.FooMethod, null, 0, 10000));
Run Code Online (Sandbox Code Playgroud)

这是具有该方法的类:

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:通常,_locker不是静态的; 在有机会完成之前,我不希望同一个线程进入该方法.我把它改为静态测试.

我的第一个想法是,这可能不起作用,因为这个类是通用的?并且每个具体类实际上是它自己的类,它们不共享_locker变量?真的吗?如果这是真的,我应该如何让具体类共享一个_locker变量?我是否需要将静态_locker变量添加到Foos可以访问的其他类中?

pho*_*oog 7

我是否需要将静态_locker变量添加到Foos可以访问的其他类中?

是.

每个Foo<T>具有不同T参数的闭合类型都有自己的静态_locker对象.你可以让Foo继承自基类,并将静态对象放在那里.然后,所有类型都将使用相同的实例.


Ser*_*kiy 6

也许

public class Foo
{
   protected static readonly object _locker = new object();
}

public class Foo<T> : Foo
{
    public void FooMethod(object stateInfo)
    {        
        if (!Monitor.TryEnter(_locker)) { return; }

        try
        {
            // Logic here
        }
        finally
        {
            Monitor.Exit(_locker);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)