のC#静的なコンストラクタをスレッド安全ですか?
-
08-06-2019 - |
質問
つまり、このシングルトン実装はスレッドに対して安全:
public class Singleton
{
private static Singleton instance;
private Singleton() { }
static Singleton()
{
instance = new Singleton();
}
public static Singleton Instance
{
get { return instance; }
}
}
解決
静的コンストラクタであることが保証されてい走りだしたアプリケーション-ドメイン前に、任意のインスタンスのクラスを作成し又は静員をご利用いただけます。 http://msdn.microsoft.com/en-us/library/aa645612.aspx
実装はスレッドに対して安全のための設備を建設し、ロックまたはnullの場合試験の構築のために必要な、シングルトンオブジェクトです。しかし、であるということではありませんがご利用のインスタンスを同期.あのさまざまなことができる;私示一つです。
public class Singleton
{
private static Singleton instance;
// Added a static mutex for synchronising use of instance.
private static System.Threading.Mutex mutex;
private Singleton() { }
static Singleton()
{
instance = new Singleton();
mutex = new System.Threading.Mutex();
}
public static Singleton Acquire()
{
mutex.WaitOne();
return instance;
}
// Each call to Acquire() requires a call to Release()
public static void Release()
{
mutex.ReleaseMutex();
}
}
他のヒント
ながらこれらすべての回答を同一の一般的な答えは、あの一点に注意してください。
覚えている可能性微汎用クラスを作成して個別の種類です。いる場合は、十分にご注意くださの実施に静的コンストラクタのための汎用タイプ。
class MyObject<T>
{
static MyObject()
{
//this code will get executed for each T.
}
}
編集:
こちらはデモンストレーション
static void Main(string[] args)
{
var obj = new Foo<object>();
var obj2 = new Foo<string>();
}
public class Foo<T>
{
static Foo()
{
System.Diagnostics.Debug.WriteLine(String.Format("Hit {0}", typeof(T).ToString()));
}
}
コンソールには:
Hit System.Object
Hit System.String
を用いた静的なコンストラクタに実際に は threadsafe.の静的コンストラクタが確実に実行されます。
から、C#言語仕様 http://msdn.microsoft.com/en-us/library/aa645612(VS.71).aspx:
の静的コンストラクタのためのクラスを実行す一にさらされます。執行の静的コンストラクタの実行による最初のイベントが発生したり、アプリケーション内のドメイン:
- クラスのインスタンスが作成されます。
- の静的イスを参照している.
であり、信頼できるシングルトンが正しくインスタンスを生成.
Zoobaいずれにおいても、素晴らしいポイント(15秒ように、目の前に!) の静的コンストラクタはスレッドを安全に共有へのアクセスシングルトン.ることが必要となる取り扱いも行う。
こちらCliffnotes版にMSDNページc#シングルトン:
以下のパターンに、必ず、しかできない:
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
private Singleton(){}
public static Singleton Instance
{
get
{
return instance;
}
}
}
を超えて、あなたがシングルトンの特徴、これまでよりも速やかにこれら二つについて無料(に関するシングルトンにはc++のみ):
- lazy建築(ない場合は、構築したいという)
- 同期
静的コンストラクタが保証される火災につき一度だけアプリのドメインでアプローチをするのは、かまわないでしょう。しかし、機能的にも、より簡潔に、インラインバージョン:
private static readonly Singleton instance = new Singleton();
スレッドの安全性が問題ときは、遅延初期化います。
の 共通の言語インフラの仕様 ることを保証"型の初期化は行って回定型のない限り、明示的に呼ばれていユーザコードです。" セ9.5.3.1.) それとも、僕がいない間についてまとめていwhacky ILのゆったり呼び出しシングルトン::.cctorを直接はお静的コンストラクタ走行から前シングルトンタイプを使用し一つのインスタンスのシングルトンが作成され、インスタンスはスレッドセーフです。
った場合、シングルトンのコンストラクタにアクセスのインスタンス性も間接的にはインスタンスプロパティはnullになります。のでなければならないことで検出しそうなると、例外がスローされ、そのインスタンスがnullの物件を取得します後に静的コンストラクタ完了のインスタンスにある手開きのドアを入ると非nullになります。
として Zoombaの回答 指摘する必要がありませシングルトンを安全にアクセスから複数のスレッド、または実施するロック機構を利用して巡るsingletonインスタンス.
の静的コンストラクタ 仕上げ 走 前 スレッドのアクセス可能。
private class InitializerTest
{
static private int _x;
static public string Status()
{
return "_x = " + _x;
}
static InitializerTest()
{
System.Diagnostics.Debug.WriteLine("InitializerTest() starting.");
_x = 1;
Thread.Sleep(3000);
_x = 2;
System.Diagnostics.Debug.WriteLine("InitializerTest() finished.");
}
}
private void ClassInitializerInThread()
{
System.Diagnostics.Debug.WriteLine(Thread.CurrentThread.GetHashCode() + ": ClassInitializerInThread() starting.");
string status = InitializerTest.Status();
System.Diagnostics.Debug.WriteLine(Thread.CurrentThread.GetHashCode() + ": ClassInitializerInThread() status = " + status);
}
private void classInitializerButton_Click(object sender, EventArgs e)
{
new Thread(ClassInitializerInThread).Start();
new Thread(ClassInitializerInThread).Start();
new Thread(ClassInitializerInThread).Start();
}
上記のコードの際に結果を出します。
10: ClassInitializerInThread() starting.
11: ClassInitializerInThread() starting.
12: ClassInitializerInThread() starting.
InitializerTest() starting.
InitializerTest() finished.
11: ClassInitializerInThread() status = _x = 2
The thread 0x2650 has exited with code 0 (0x0).
10: ClassInitializerInThread() status = _x = 2
The thread 0x1f50 has exited with code 0 (0x0).
12: ClassInitializerInThread() status = _x = 2
The thread 0x73c has exited with code 0 (0x0).
もの静的コンストラクタを長時間の走行は、その他のスレッドを停止し、待ち状態となります。すべてのスレッドの値を_xセット下部の静的コンストラクタです。
される方もいるでしょうpedanticがなければならないと思うか静的コンストラクタではなく静的な型initializers, この小さな デモの静的繰返しのコンストラクタ依存性を示す。
静的コンストラクタはスレッドで安全です。また、チェックアウトのシングルトンでDeveloperZen:http://www.developerzen.com/2007/07/15/whats-wrong-with-this-code-1-discussion/
はその他の回答をほぼ正しいありがとを条件と静的コンストラクタ.
として第 II.10.5.3.3レースとデッドロック の ECMA-335共通言語 インフラ
タイプの初期化だけではない作に行き詰まりがない限り、当コード というタイプから初期化子(直接または間接的に確かめられ を呼び出しブロック。
次のコードは結果的に行き詰まり
using System.Threading;
class MyClass
{
static void Main() { /* Won’t run... the static constructor deadlocks */ }
static MyClass()
{
Thread thread = new Thread(arg => { });
thread.Start();
thread.Join();
}
}
原作者Igor Ostrovsky、メールアドレスを入力 こちらの.