私は、テストのために、自分のタイマーメソッド(FooMethod)を一度に1つだけ実行したいという状況があります。次の例では、FooMethodがデリゲートとしてタイマーに渡されます。このクラスの多くの具体的な例があります。私は、_lockerを静的にすることで、FooMethod()の1つのインスタンスだけが一度に処理すると考えました。しかし、私がアプリケーションを実行すると、TryEnter()行を複数のスレッドが一度に通過しています。Generic Classを使用したMonitor.TryEnter
これは、新しいタイマーに各クラスを追加する方法です。これは、各FOOインスタンスに対して、ループ内で、行われる:
_timers.Add(new Timer(foo.FooMethod, null, 0, 10000));
、これはそのメソッドを有するクラスである:
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);
}
}
}
注:通常は、_lockerは静的ではありません。私は完了するチャンスを得る前に、同じスレッドがメソッドに入ることを望んでいません。私はテストのために静的に変更しました。
私の最初の考えは、クラスが一般的なので動作していない可能性がありますか?そして、それぞれの具象クラスは実際には独自のクラスであり、_locker変数を共有していませんか?本当?それが本当の場合、具体的なクラスを_locker変数をどのように共有する必要がありますか? Foosがアクセスする他のクラスに静的な_locker変数を追加する必要がありますか?
非常に興味深い質問です。 +1 – spender
同じスレッド*がロックを再入力できることに注意してください(ただし、再帰がある場合のみ)。これは、ロックのためのものです:*異なる*スレッドが同じリソースを使用するのを防ぎます。 – phoog
@spenderありがとうございます。そして、私は理解しています。私の静的変数の目標は、複数のスレッドが同時にそのメソッドを処理しないようにすることでした。しかし、それは動作していません。 –