99

[ThreadStatic]ThreadLocal<T>ジェネリックを使用しながら、属性を使用して定義されます。なぜ異なる設計ソリューションが選ばれたのですか? この場合、属性よりもジェネリックを使用することの利点と欠点は何ですか?

4

3 に答える 3

121

コメントに記載されているブログ投稿では明示されていませんが、非常に重要であることがわかりました。それ[ThreadStatic]は、すべてのスレッドに対して自動的に初期化されるわけではないということです。たとえば、これがあるとします:

[ThreadStatic]
private static int Foo = 42;

これを使用する最初のスレッドは、にFoo初期化されていることがわかります42。しかし、後続のスレッドはそうしません。初期化子は、最初のスレッドに対してのみ機能します。そのため、初期化されているかどうかを確認するコードを作成する必要があります。

ThreadLocal<T>Reed のブログが示すように、最初にアイテムにアクセスする前に実行される初期化関数を提供できるようにすることで、この問題を解決します。

[ThreadStatic]私の意見では、代わりにを使用するメリットはありませんThreadLocal<T>

于 2013-08-20T14:06:42.810 に答える
16

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 を使用します。

于 2016-09-27T02:07:39.777 に答える