3

私は SyncRoot の概念が初めてです。私が知る限り、ロックに使用されるオブジェクトは非公開にする必要があります。

ただしHashTable、パブリック プロパティ がありSyncRootます。これは、プライベート SyncRoot オブジェクトの単なるラッパーです。コレクションを列挙するときはロックすることをお勧めしますHashTable.SyncRoot

プライベートではなくなったため、デッドロックで失敗する可能性があるようです。本当にスレッドセーフですか?

独自のプライベート ロック メカニズムを作成するとどうなりますか? private readonly object _syncObject;

どちらが優れているのか、その理由は?

4

2 に答える 2

7

いいえ、それは .NET 1.x アプローチの本当の問題ではありません。パブリックにアクセスできる必要があるため、プロパティはパブリックです。問題は、コレクションを列挙することです。スレッドセーフな方法でそれを実装する方法はありません。列挙を開始すると自動的にロックし、完了したらロックを解除するメカニズムはありません。IEnumerable には Completed メソッドがなく、IDisposable を継承しません。

したがって、コードを安全に列挙できるようにするには、lock オブジェクトにアクセスする必要があります。そのため、そのオブジェクトをロックして foreach ステートメントをラップできます。したがって、パブリック SyncRoot プロパティ。

しかし、多くのプログラマーが陥った最大の落とし穴は、それは必要ないと思い込んでいたことです。Synchronized プロパティは、すべての状況でスレッド セーフなコレクションのスレッド セーフなラッパーを返すという概念を受け入れます。そうではありません。

于 2012-01-06T13:44:17.727 に答える
5

ICollection.SyncRootジェネリック前のコレクションにのみあります。基本的に廃止されています。

これは、まさにあなたが言及した理由により、汎用コレクションで削除されました-必要なプロパティを持つコレクションへのアクセスを制御するには、SyncRoot を使用するのではなく、独自のロックメカニズムを使用する必要があります (ロックをプライベートに保ち、デッドロックを回避します...)。オブジェクトであり、コードが魔法のようにスレッドセーフであると仮定します。

于 2012-01-06T12:13:52.490 に答える