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)

モジュール間でロックを共有することが問題を解決する良い方法であるという状況はありますか? パブリック オブジェクトのロックに関するガイダンスはありますか?

4

2 に答える 2

5

コードが臭いなら、それは悪臭を放ちます。

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

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

ロックを公開することは、開発者が実際に取得する必要のないロックを取得すること、または取得した結果を実際に考慮していないことを奨励する方法です。

あなたはおそらく私よりも公式のリファレンスが欲しいでしょう! 「lock」ステートメントのドキュメントを試してください。

一般に、パブリック型、またはコードの制御を超えたインスタンスのロックは避けてください。一般的な構成要素 lock (this)、lock (typeof(MyType))、および lock ("myLock") は、次のガイドラインに違反しています。

ロック (これ) は、インスタンスがパブリックにアクセスできる場合に問題になります。

lock (typeof (MyType)) は、MyType が公開されている場合に問題になります。

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

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

ソース: http://msdn.microsoft.com/en-us/library/c5kehkcz(v=vs.80).aspx

于 2012-05-08T04:06:52.370 に答える
2

PublicStaticLockObject は、PublicStaticResource へのアクセスを同期することを目的としている場合があります。その場合、誰もがオブジェクトをうまく操作すれば、問題に遭遇することはありません。しかし、誰かがそのロック オブジェクトをのリソースに使用すると、デッドロックのリスクがあります。また、オブジェクトは読み取り専用ではないため、誰かが新しいオブジェクトに置き換えることができることに注意してください。それもトラブルの原因になります。

そのため、ClassX はプライベート ロック オブジェクトを宣言してから、public static メソッドを通じて public static リソースを公開する必要があります。これらのメソッドには、リソースを保護するためのロック ステートメントが含まれます。たとえば、前に:

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);
    }
}

後:

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);
    }
}
于 2012-05-08T05:28:48.883 に答える