2013-03-14 23 views
21

私はHTTPリスナーを使って書いているHTTPサーバを持っています。スレッド内のどこからでもアクセスできるものとして何らかの変数を宣言したいと思います。スレッド内でグローバル変数を設定する - C#

  • Webサーバークラスはインスタンスベースであるため、静的変数は実際には使用できません。
  • すべてのコードが1つのクラスに含まれているため、インスタンス変数を使用できますが...わかりません。

私は辞書を使用すると思った:Dictionary</*[type of Thread ID here]*/,ThreadData>しかし、私はスレッドの問題がある可能性があります。 ThreadData、おそらくはクラスインスタンスになりますが、効率的なものに応じて構造体を使用することがあります。

  • つのスレッドがのみ辞書に独自のエントリのために頼むように辞書にアクセスするとき、私は、任意のスレッド関連の問題があるだろうスレッドIDとプログラムそれに辞書をキーイングでしょうか?
  • 各スレッドは独自のエントリを追加します。新しいスレッド項目を追加しているときに辞書をロックする必要がありますか?もしそうなら、別のロックオブジェクトを使用して、スレッドがその間に自分のデータにアクセスできるようにすることができますか?

同時並行辞書を使用する利点はありますか?スレッドセーフな方法がありますか?

私は現在ThreadPool.QueueUserWorkItemを使用しています。私は、これが各項目に新しいスレッドを使用しているかどうかはわかりません。そうでなければ、私はそれをコンテキストに合わせることもできます。

更新:ThreadPool class - MSDNによれば、スレッドを再利用します。そして、スレッドデータをクリアしません。

スレッドプールがスレッドを再利用する場合、スレッドローカルストレージまたはThreadStaticAttribute属性でマークされたフィールドのデータはクリアされません。したがって、ThreadStaticAttribute属性でマークされたスレッドローカルストレージまたはフィールドを調べるメソッドは、スレッドプールスレッドの以前の使用から残っている可能性があります。

+0

考えるあなたは[BackgroundWorkerの](http://msdn.microsoft.com/en-をサブクラス化しようとしたことがありus/library/system.componentmodel.backgroundworker.aspx)クラス? – Romoku

+0

ワーカースレッドのエントリポイントが異なり、ワーカーロジックを自分で作成するため、古いスレッドデータを消去することは問題ではありません。 – Gene

答えて

27

一つの解決策は、ThreadStatic属性で、のpublic staticフィールドを使用することです:ThreadStaticAttributeでマークされた

[ThreadStatic] 
public static int ThreadSpecificStaticValue; 

静的フィールドは スレッド間で共有されていません。実行中の各スレッドは、フィールドの別のインスタンス を持ち、独立してそのフィールドの値を設定および取得します。フィールドが異なるスレッドでアクセスされた の場合、異なる値が格納されます。

あなたはHTTPサーバーを作成したいなぜ、使用 SignalRは、変人の答えを探します
+0

ニートそのことを知らなかった。 – Gene

+0

でも私は+2ができたらいいなあ! –

+0

この方法とGeneの答えの違いは何ですか?彼らはどちらも明らかに同じことを成し遂げています。 Geneのメソッドはスレッドのどこからでもアクセスできると思いますが、これは標準的なアクセス規約に従います。これは簡単です。あなたに+1してください:) –

0

Webサーバーがインスタンスベースの場合は、必要なデータをすべてそこに保存してください。各インスタンスが特定のスレッドにロックされている場合、問題はありません。

+0

いいえ、各クライアント要求は独自のスレッドを取得します。 –

+0

@ArlenBeilerあなたのマシンにはいくつのコアがありますか?すべてのリクエストをスレッディングすることはかなり最適ではありません。いくつかのスレッドで作業を分散する要求スケジューラを書く方が良いでしょう。 – Romoku

+0

申し訳ありませんが、 'ThreadPool.QueueUserWorkItem'を使用しています。私の悪い。 –

5

あなたは、スレッドクラスのストレージ・メカニズムに組み込まれて使用することもできます

public class Program 
{ 
    private static LocalDataStoreSlot _Slot = Thread.AllocateNamedDataSlot("webserver.data"); 

    public static void Main(string[] args) 
    { 
    var threads = new List<Thread>(); 

    for (int i = 0; i < 5; i++) 
    { 
     var thread = new Thread(DoWork); 
     threads.Add(thread); 
     thread.Start(i); 
    } 

    foreach (var thread in threads) thread.Join(); 
    } 

    private static void DoWork(object data) 
    { 
    // initially set the context of the thread 
    Thread.SetData(_Slot, data); 

    // somewhere else, access the context again 
    Console.WriteLine("Thread ID {0}: {1}", Thread.CurrentThread.ManagedThreadId, Thread.GetData(_Slot)); 
    } 

} 

出力例:

enter image description here

だけでなく、スレッドプールによって生成されたスレッドで動作します。

関連する問題