web-dev-qa-db-ja.com

静的メソッドのLock()

静的メソッドを使用して設定xmlファイルに書き込むマルチスレッドアプリケーションがあります。ファイルが同時に2回更新されることを避けたい(アクセス/書き込み例外の原因)。

それ、どうやったら出来るの?

これは機能しません:

namespace Program
{
    public class Settings
    {
        private static void SetSettingsValue (string settings, string value)
        {
            // make this thread safe to avoid writing to a locked settings xml file
            lock (typeof(Settings))
            {
                //write data to xml file
            }
        }
    }
}
19
koen

Lock()の概念は、参照できる既存のオブジェクトを使用し、アクセスを許可するかどうかを制御するために使用することです。

static object SpinLock = new object();

lock(SpinLock)
{
   //Statements
}

実行がlock()ブロックを離れると、参照が解放され、コードブロックの実行を待機している他のスレッドを続行できます(もちろん、一度に1つずつ)。

35
Erik Noren

別の静的ロックオブジェクトを作成して使用する必要があります。文字列を使用しないでください!文字列は自動的にインターンされ、プログラムで宣言された各文字列のインスタンスは1つしかないため、ロックへの排他的アクセスを保証することはできません。

これを行う必要があります:

public class A {
    private static Object LOCK = new Object();

    private static void foo() {
        lock(LOCK) {
            // Do whatever
        }
    }
}

(構文が正しくない可能性があります。私はJavaの人ですが、ロックと文字列のインターンに関する同じルールがC#にも適用されます)

Lockキーワードは相互排他ロックを強制します。一度に特定のオブジェクトをロックできるのは1つのスレッドのみです。 2番目のスレッドがfooを呼び出すと、最初のスレッドがロックブロックを終了するまでブロックされます。

持ち帰りメッセージ:プライベート静的変数の静的メソッドロックの場合。 Stringsまたはtypeof(...)をロックしないでください。これは、他の誰もそのオブジェクトを使用していないことを保証できないためです。オブジェクトをプライベートにして新しく作成することで、他のユーザーが触れていないことがわかっているオブジェクトを常にロックします。

40
Cameron Skinner