14

ThreadStatic変数を使用して一部のデータを格納していますが、スレッドに格納したデータが終了してThreadPoolにリリースされた後も、そこに残っているのではないかと心配しています。スレッドを終了する前に、ThreadStatic変数をクリアすることを心配する必要がありますか?または、次のQueueUserWorkItemに「渡す」前に、ThreadPoolがこれを実行しますか?これは私にとって特に重要です。なぜなら、私のアプリの他のスレッドがThreadStatic変数の観点から機能するためのクリーンな状態になっていることを確認する必要があるからです。ありがとう!

4

2 に答える 2

12

スレッド プール (設計による) は、呼び出し間でスレッドを有効に保ちます。これは、QueueUserWorkItem への呼び出し間で ThreadStatic 変数が保持されることを意味します。

この動作も当てにすべきではありません。ThreadPool は (最終的にはその裁量で) スレッドを解放して終了させ、必要に応じて新しいスレッドを構築します。

ただし、これで問題が発生した場合は、設計に疑問を呈します。特定の決定論的な ThreadStatic データを QueueUserWorkItem で使用する必要がある場合、スレッド ルーチンは、自分でスレッドを処理するのに適している可能性があります。ThreadStatic と ThreadPool は、常に優れた組み合わせであるとは限りません。(ThreadPool がスレッドを管理するため) ThreadStatic 変数を実際に利用してメリットを得るには、必ずしも十分な制御ができるとは限りません。2 つの作業項目が同じスレッドにあるか、異なるスレッドにあるか、threadstatic 変数を (再) 初期化する必要があるかどうかなどはわかりません。

于 2009-05-13T01:05:46.910 に答える
6

メソッド間に残ると思います。もちろん、疑わしい場合は、ワーカー メソッドの開始時にスレッド静的変数をリセットしてください。または、try/を使用して、各作業単位のfinallyに値をクリアします。

(編集)

それらが実際に残っていることを証明するのは非常に簡単です。上記はすぐに 0 より大きい数値の出力を開始します (異なるワーカーが分離されている場合、毎回 0 が予想されます)。

[STAThread]
static void Main()
{
    for (int i = 0; i < 50; i++)
    {
        ThreadPool.QueueUserWorkItem(DoStuff);
    }
    Console.ReadLine();
}
static void DoStuff(object state)
{
    Console.WriteLine(Thread.CurrentThread.ManagedThreadId + ": " + value++);
    Thread.Sleep(20);
}
[ThreadStatic]
static int value;
于 2009-05-12T21:56:08.010 に答える