「SyncRoot」プロパティを探す場合はSyncRoot
、コレクションと組み合わせてロックを使用するときにこのプロパティを使用することをお勧めします。下位互換性のために後のコレクションでサポートされていますが、インターフェイスを明示的に実装することで非表示になる傾向があるのには理由があります。本当に、そのSyncRoot
アイデアはあまり良いものではありませんでした。
この場合、スレッドセーフなコレクションについて話しているので、必要性はさらに少なくなります。System.Web.Caching.Cache
独自のロック(または他のメカニズム、特定のアプローチではスレッドセーフではなくスレッドセーフに指定されている)を実行するため、複数のスレッドにわたってコレクションにアイテムを追加、アクセス、および削除しても、アイテムが破損することはありません。
残っている唯一のリスクは、オブジェクト自体がスレッドセーフでない場合、または同じスレッドでコレクションからオブジェクトに複数回アクセスする場合です。
2つ目は、そうしないことで簡単に回避できます。もし、するなら:
(HttpRuntime.Cache.Get(someKey) as SomeType).SomeMethod();
(HttpRuntime.Cache.Get(someKey) as SomeType).SomeOtherMethod();
これは、2回目の呼び出しで最初の呼び出しとは異なるオブジェクトを処理する可能性がある場合にのみ意味があります。それ以外の場合は、簡単に解決できます。
SomeType obj = HttpRuntime.Cache.Get(someKey) as SomeType;
obj.SomeMethod();
obj.SomeOtherMethod();
Get
(メソッドを繰り返し呼び出さないことで、パフォーマンスもわずかに向上します。
さまざまなスレッドの呼び出しについて心配する必要があるSomeMethod()
とSomeOtherMethod()
同時に、それらのメソッドがスレッドセーフであることを確認するか、問題のオブジェクトに関連するオブジェクトをロックする必要があります。ほとんどの場合、オブジェクトに関連するオブジェクトの最も明白な選択は、そのオブジェクト自体です。したがって:
SomeType obj = HttpRuntime.Cache.Get(someKey) as SomeType;
lock(obj)
{
obj.SomeMethod();
obj.SomeOtherMethod();
}
(とがスレッドセーフであったとしても、それらの組み合わせがスレッドセーフでない場合は、これを行う必要がある可能性があることに注意してくださいSomeMethod()
。SomeOtherMethod()
たとえば、オブジェクトの状態について最初に報告され、それに基づいて実行するかどうかを決定した場合などです。 2番目の場合、通常は、最初のメソッド呼び出しと2番目のメソッド呼び出しの間で状態が変化しないようにロックする必要があります)。
もちろん、オブジェクトに対する他のすべての操作は、同じ方法でロックする必要があります。ユニットとして同期する必要のあるオブジェクトが複数ある場合は、さらに複雑になります。次に、問題のオブジェクトを単にロックするという、どのオブジェクトをロックするかについてのより複雑なルールが必要です。「問題のオブジェクト」は1つもないからです。