ICollection の syncroot のポイントを理解しようとしています。コレクションをロックしないのはなぜですか?
lock(myCollection)
{
//do stuff to myCollection
}
対
lock(myCollection.SyncRoot)
{
//do stuff to myCollection
}
ICollection の syncroot のポイントを理解しようとしています。コレクションをロックしないのはなぜですか?
lock(myCollection)
{
//do stuff to myCollection
}
対
lock(myCollection.SyncRoot)
{
//do stuff to myCollection
}
通常、スレッドの安全性が深刻な懸念事項である場合、これらのオプションはどちらも避けます。
通常、はるかに優れたオプションは、独自のプライベート変数を維持し、それが必要なすべてのメソッド (コレクションにアクセスするパブリック API 全体を含む) でロックすることです。
本当の危険は、外部の世界に公開されている、または公開される可能性のある型をロックすることで、「外部の世界」が同期を台無しにする可能性を開くことです。複数のロックが使用されている場合、デッドロックが発生する可能性があります (予期しないものに対して外部がロックしている場合)。
プライベート変数を作成し、それを排他的にロックすることで、状況を「制御」しています。これにより、何が起こっているのかがより明確になります。さらに、ロックが非常に明確であるため、特に後でコードを保守するときに、複数のオブジェクト間の同期が容易になります。
コレクション全体をロックしているロック(this)を行うと信じているため、SyncRootをロックしないでください。 ロックする場合は、オブジェクトを作成してロックする必要があります。例えば
public class MyClass
{
get {return lock(_lockObject) _myCollection ; }
set {lock(_lockObject) _myCollection.Add(value); }
private List<string> _myCollection = new List<string>();
private object _lockObject = new object();
}
より明確にするために、lock(myCollection.SyncRoot) と lock(myCollection) は同じことを行います。
プロパティ SyncRoot は次のように見えるため
get {これを返します。}