2012-05-08 6 views
2

私はいくつかのコードを見直しています。私は、ロックに使用されたオブジェクトに関するすべての参照を見つけました。次の結果が得られました。公開オブジェクトをロックし、モジュール間で共有する

保護する必要のあるユーザーを保護するために、すべてのファイル/クラス/メンバー名を置き換えました。

C:\Sln1\ProjX\ClassX.cs - (17, 26) : public static object PublicStaticLockObj = new object(); 
C:\Sln1\Proj1\Class1.cs - (193, 20) : lock (ClassX.PublicStaticLockObj) 
C:\Sln1\Proj1\Class1.cs - (228, 20) : lock (ClassX.PublicStaticLockObj) 
C:\Sln1\Proj1\Class1.cs - (92, 20) : lock (ClassX.PublicStaticLockObj) 
C:\Sln1\Proj2\Class2.cs - (115, 20) : lock (ClassX.PublicStaticLockObj) 
C:\Sln1\Proj2\Class2.cs - (181, 20) : lock (ClassX.PublicStaticLockObj) 
C:\Sln1\Proj2\Class2.cs - (216, 20) : lock (ClassX.PublicStaticLockObj) 
C:\Sln1\Proj3\Class3.cs - (160, 20) : lock (ClassX.PublicStaticLockObj) 
C:\Sln1\Proj3\Class3.cs - (195, 20) : lock (ClassX.PublicStaticLockObj) 
C:\Sln1\Proj3\Class3.cs - (95, 20) : lock (ClassX.PublicStaticLockObj) 
C:\Sln1\Proj4\Class4.cs - (133, 20) : lock (ClassX.PublicStaticLockObj) 
C:\Sln1\Proj4\Class4.cs - (252, 20) : lock (ClassX.PublicStaticLockObj) 
C:\Sln1\Proj4\Class4.cs - (286, 20) : lock (ClassX.PublicStaticLockObj) 
C:\Sln1\Proj5\Class5.cs - (252, 20) : lock (ClassX.PublicStaticLockObj) 
C:\Sln1\Proj5\Class5.cs - (320, 20) : lock (ClassX.PublicStaticLockObj) 
C:\Sln1\Proj5\Class5.cs - (360, 20) : lock (ClassX.PublicStaticLockObj) 
C:\Sln1\Proj6\Class6.cs - (112, 20) : lock (ClassX.PublicStaticLockObj) 
C:\Sln1\Proj6\Class6.cs - (177, 20) : lock (ClassX.PublicStaticLockObj) 
C:\Sln1\Proj6\Class6.cs - (212, 20) : lock (ClassX.PublicStaticLockObj) 
C:\Sln1\Proj7\Class7.cs - (165, 20) : lock (ClassX.PublicStaticLockObj) 
C:\Sln1\Proj8\Class8.cs - (129, 20) : lock (ClassX.PublicStaticLockObj) 
C:\Sln1\Proj8\Class8.cs - (198, 20) : lock (ClassX.PublicStaticLockObj) 
C:\Sln1\Proj8\Class8.cs - (233, 20) : lock (ClassX.PublicStaticLockObj) 
C:\Sln1\Proj9\Class9.cs - (156, 20) : lock (ClassX.PublicStaticLockObj) 
C:\Sln1\Proj9\Class9.cs - (191, 20) : lock (ClassX.PublicStaticLockObj) 
C:\Sln1\Proj9\Class9.cs - (90, 20) : lock (ClassX.PublicStaticLockObj) 

モジュール間でロックを共有することは問題を解決する良い方法です。公共の物体をロックするためのガイダンスはありますか?

+0

public static class ClassX { public static FileStream Stream { get; private set; } public static object PublicStaticLockObj = new object(); } public class ClassY { public void WriteToTheGlobalStream(byte b) { lock (ClassX.PublicStaticLockObj) ClassX.Stream.WriteByte(b); } } 

後。それは少し魚の臭いがする。これらのロックはすべて単一のデータ構造を保護しているのですか、無関係な構造の束にロックを使用していますか? – Enigmativity

+0

他の人が言っているように、おそらく*悪い考えですが、ロック/シリアライズに関するコンテキストがなければ、それを置き換えるための特定のパターン/アプローチを推奨することは難しいでしょう。 –

+0

もしあなたがそれをやるつもりならば、 'lock(typeof(ClassX))'をしてもよいでしょう。 –

答えて

5

コードが匂いがすると、その匂いがします。

同期メカニズムとしてのロックの主な弱点は、それらが構成可能ではないことです。複数のロックを取得する必要があり、非常に簡単にデッドロックが発生します。

デッドロックを防止する唯一の方法は、ロックを獲得する状況を絶対的に必要な場所に制限し、ロックが保持されている間に実行するアクションを制限することです。他のロックを取る可能性のあるものは避けてください。また、何らかの操作をしても効果的に推進されているため、一度に複数のスレッドをブロックすることができるため、ブロック、スリープ、または長時間かかることは避けてください。

ロックをパブリックにすることは、開発者が本当に必要としないロックを取ることを奨励する方法であり、実際には取ることの結果を考慮していないということです。

おそらく私よりも正式な参照が必要です。 'lock'ステートメントのドキュメントを試してください。

一般に、パブリックタイプまたはコードの制御を超えたインスタンスではロックしないでください。

ロック(this)、ロック(typeof(MyType))およびロック( "myLock")は、このガイドラインに違反しています。

ロック(typeof(MyType))は、MyTypeが一般にアクセス可能な場合に問題になります。

同じ文字列を使用するプロセス内の他のコードは同じロックを共有するため、lock( "myLock")は問題です。

ロックするプライベートオブジェクトを定義すること、またはすべてのインスタンスに共通のデータを保護するためのプライベート静的オブジェクト変数を定義することをお勧めします。

出典:PublicStaticLockObjectは誰もが対象とうまく果たしているならば、その場合には、あなたがトラブルに実行するつもりはない、いくつかのPublicStaticResourceへのアクセスを同期することを目的とすることができるhttp://msdn.microsoft.com/en-us/library/c5kehkcz(v=vs.80).aspx

2

。しかし、誰かがのリソースで別のリソースに対してそのロックオブジェクトを使用すると、デッドロックの危険性があります。また、オブジェクトは読み込み専用ではないため、新しいオブジェクトで置き換えることもできます。それもトラブルを引き起こす可能性があります。

そのため、ClassXはプライベートロックオブジェクトを宣言してからパブリック静的リソースを公開静的メソッドで公開する必要があります。これらのメソッドにはリソースを保護するためのロック文が含まれます。たとえば、前に:あなたはあなたのコード内の多くの場所のための単一のすべての強力なロック・オブジェクトを持っているように思える

public static class ClassX 
{ 
    private static FileStream Stream { get; set; } 
    private static object PublicStaticLockObj = new object(); 
    public static void WriteToTheStream(byte b) 
    { 
     lock (PublicStaticLockObj) 
      Stream.WriteByte(b); 
    } 
} 

public class ClassY 
{ 
    public void WriteToTheGlobalStream(byte b) 
    { 
     ClassX.WriteToTheStream(b); 
    } 
} 
関連する問題