Définition d'une variable globale dans un thread-C#

J'ai un serveur HTTP que j'écris en utilisant HTTP listener, et je voudrais en quelque sorte déclarer certaines variables comme accessibles depuis n'importe où dans un thread.

  • ma classe de serveur web est instanciée, donc je ne peux pas vraiment utiliser une variable statique.
  • je pourrais utiliser une variable d'instance, comme tout le code est dans une classe, mais...Je ne sais pas.

J'ai pensé à utiliser un dictionnaire: Dictionary</*[type of Thread ID here]*/,ThreadData>, mais je crains qu'il puisse y avoir des problèmes de threading. ThreadData serait probablement être une instance de classe, mais je pourrais utiliser une structure, en fonction de ce qui serait plus efficace.

  • Si je tapais le dictionnaire sur les ID de Thread et que je le programmais pour qu'un thread ne demande que sa propre entrée dans le dictionnaire, y aurait-il des problèmes liés au thread lors de l'accès au dictionnaire?
  • chaque thread ajouterait sa propre entrée. Devrais-je verrouiller le dictionnaire pendant que j'ajoute de nouveaux éléments de thread? Si oui, serais-je capable d'utiliser un séparer l'objet de verrouillage pour permettre aux threads d'accéder à leurs propres données entre-temps?

Y aurait-il un avantage à utiliser un dictionnaire concurrent? Existe-t-il un autre moyen plus sûr pour les threads?

J'utilise actuellement ThreadPool.QueueUserWorkItem. Je ne sais pas avec certitude que cela utilise un nouveau thread pour chaque élément. Si ce n'est pas le cas, je pourrais aussi le lier au contexte.

Mise à jour: selon ThreadPool class - MSDN, il réutilise les threads. Et il ne dégage pas de fil données.

Lorsque le pool de threads réutilise un thread, il n'efface pas les données dans le stockage local du thread ou dans les champs marqués avec L'attribut ThreadStaticAttribute. Par conséquent, lorsqu'une méthode examine le stockage local de thread ou les champs marqués avec L'attribut ThreadStaticAttribute, les valeurs qu'elle trouve peuvent être laissées par une utilisation antérieure du thread de pool de threads.

22
demandé sur Arlen Beiler 2013-03-14 20:05:02

4 réponses

Une solution serait d'utiliser un public static champ, avec la ThreadStatic attribut:

[ThreadStatic]
public static int ThreadSpecificStaticValue;

Un champ statique marqué avec ThreadStaticAttribute n'est pas partagé entre threads. Chaque thread d'exécution a une instance distincte du champ, et définit et obtient indépendamment des valeurs pour ce champ. Si le champ est accessible sur un thread différent, il contiendra une valeur différente.

31
répondu ken2k 2013-03-14 16:22:14

Vous pouvez utiliser le mécanisme de stockage intégré de la classe thread:

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));
  }

}

Exemple de sortie:

entrez la description de l'image ici

Cela fonctionnera également avec les threads générés par le pool de threads.

5
répondu Gene 2013-03-14 16:21:42

Si votre serveur web est basé sur une instance, pourquoi ne pas y conserver toutes les données requises? Si chaque instance est verrouillée sur un certain thread, il ne devrait pas y avoir de problème.

0
répondu rhughes 2013-03-14 16:08:57

Pourquoi voulez-vous créer un Serveur HTTP , Utilisez SignalR , semble bizarre réponse, mais pensez-y

0
répondu TalentTuner 2013-03-14 16:25:30