[ThreadStatic]
ThreadLocal<T>
ジェネリックを使用しながら属性を使用して定義されています。なぜ異なる設計ソリューションが選ばれたのですか?この場合、ジェネリックオーバー属性を使用する利点と欠点は何ですか?
[ThreadStatic]
ThreadLocal<T>
ジェネリックを使用しながら属性を使用して定義されています。なぜ異なる設計ソリューションが選ばれたのですか?この場合、ジェネリックオーバー属性を使用する利点と欠点は何ですか?
回答:
コメントに記載されたブログの投稿では明確にされていませんが[ThreadStatic]
、すべてのスレッドに対して自動的に初期化されないことが非常に重要であることがわかりました。たとえば、これがあるとします:
[ThreadStatic]
private static int Foo = 42;
これを使用する最初のスレッドは、にFoo
初期化され42
ます。しかし、その後のスレッドはそうしません。初期化子は最初のスレッドでのみ機能します。したがって、コードが初期化されているかどうかを確認するコードを記述する必要があります。
ThreadLocal<T>
アイテムに初めてアクセスする前に実行される初期化関数(Reedのブログに示されている)を指定できるようにすることで、この問題を解決します。
私の意見では、の[ThreadStatic]
代わりに使用する利点はありませんThreadLocal<T>
。
ThreadLocal<T>
は.NET 4以降で利用可能であり、ThreadStatic
属性は3.5以下でも利用可能です。
ThreadLocal<T>
実装しIDisposable
、通常は実装IDisposable
も強制します。これにより、呼び出し元があなたを処分し、したがって実装IDisposable
も
ThreadLocal
または使用に非常に注意ThreadStatic
します。これらの値は、割り当てたタスクだけでなく、プールスレッドの存続期間全体にわたって残ります。それはあなたにいくつかのかなり非自明な方法で問題を引き起こす可能性があります。詳細については、stackoverflow.com / questions / 561518 / …および同様の質問をご覧ください。
static
か?msdn.microsoft.com/en-us/library/…を
ThreadStatic Initialize on first thread、ThreadLocal Initialize for each thread。以下は簡単なデモです:
public static ThreadLocal<int> _threadlocal =
new ThreadLocal<int>(() =>
{
return Thread.CurrentThread.ManagedThreadId;
});
public static void Main()
{
new Thread(() =>
{
for (int x = 0; x < _threadlocal.Value; x++)
{
Console.WriteLine("First Thread: {0}", x);
}
}).Start();
new Thread(() =>
{
for (int x = 0; x < _threadlocal.Value; x++)
{
Console.WriteLine("Second Thread: {0}", x);
}
}).Start();
Console.ReadKey();
}
ThreadStaticの主な目的は、スレッドごとに変数の個別のコピーを維持することです。
class Program
{
[ThreadStatic]
static int value = 10;
static void Main(string[] args)
{
value = 25;
Task t1 = Task.Run(() =>
{
value++;
Console.WriteLine("T1: " + value);
});
Task t2 = Task.Run(() =>
{
value++;
Console.WriteLine("T2: " + value);
});
Task t3 = Task.Run(() =>
{
value++;
Console.WriteLine("T3: " + value);
});
Console.WriteLine("Main Thread : " + value);
Task.WaitAll(t1, t2, t3);
Console.ReadKey();
}
}
上記のスニペットではvalue
、メインスレッドを含め、スレッドごとに個別のコピーがあります。
したがって、ThreadStatic変数は、それが作成されたスレッドを除く他のスレッドではデフォルト値に初期化されます。
独自の方法で各スレッドの変数を初期化する場合は、ThreadLocalを使用します。