2012-01-20 9 views
2

私はこのように見ているいくつかのコードがあります。System.Threading.Timerを使用して同期しないでください。

using System.Threading; 

public sealed class MyClass : IDisposable { 
    private readonly Timer _timer; 

    public MyClass() { 
     _timer = new Timer(MyCallback); 
    } 

    public void SomeMethod() { 
     lock (_timer) { 
      ... 
     } 
    } 

    ... 

}

私はコード解析(FxCopの)を実行すると、私は
CA2002 : Microsoft.Reliability : 'MyClass.SomeMethod' locks on a reference of type 'Timer'. Replace this with a lock against an object with strong-identity.

I found some documentation hereエラーメッセージが表示されますが。

オブジェクトは、アプリケーションドメインの境界を越えて直接アクセスできる場合、弱いアイデンティティを持つと言われています。

は、どのように私のプライベートタイマーオブジェクトは、AppDomainを越えてアクセスすることができますか?私が考えることができる唯一の理由は、Timerクラスがいくつかのグローバルシステムハンドルをラップする場合ですが、そのハンドルがロックにどのように関与しているのか分かりません。

ありドキュメントページ上の弱いクラスのリストですが、タイマーは言及されていません。 MemomoryStreamもリストにはありませんが、例に含まれています。ローカルのMemoryStreamオブジェクトはどのように弱いのですか?

答えて

4

Timerは、私は疑う、それは文句を言っている理由である、MarshalByRefObjectを拡張します。

個人的に私が唯一のみあなたのコードが知っていることができますプライベートオブジェクトにロックをお勧めします:

using System.Threading; 

public sealed class MyClass : IDisposable { 
    private readonly Timer _timer; 
    private readonly object _mutex = new object(); 

    public MyClass() { 
     _timer = new Timer(MyCallback); 
    } 

    public void SomeMethod() { 
     lock (_mutex) { 
      ... 
     } 
    } 

    ... 
} 

Timerthisなどをロックすることを決定したかどうかを心配する必要はありませんその方法を

+0

感謝。私はそれを回避する方法を知っていますが、パブリックオブジェクトの潜在的なロックが問題である場合、なぜいくつかのクラスがリストされている理由を理解していません。 – adrianm

+0

@adrianm:パブリックオブジェクトに対する潜在的なロックは一般的に問題です。 'MarshalByRefObject'をロックすることで、あるAppDomainで実行されているコードが別のAppDomainのオブジェクトをロックすることができるため、さらに問題が発生する可能性があります。 –

+0

私の個人的なMarshalByRefObject自体が他のappdomainに見えるようになっている可能性がありますか?そうでなければ、他の誰がロックでそれを使うことができるのか分かりません。 – adrianm

2

あなたはTimerは、そのインスタンス上で自分自身をロックしていないことを確認することはできません。最高のものはnew object()です。

関連する問題