J'ai un serveur HTTP que j'écris en utilisant un auditeur HTTP, et j'aimerais déclarer en quelque sorte que certaines variables sont accessibles de n'importe où dans un thread.
J'ai pensé à utiliser un dictionnaire: Dictionary</*[type of Thread ID here]*/,ThreadData>
, mais je crains qu'il y ait des problèmes de thread. ThreadData
serait probablement une instance de classe, mais je pourrais utiliser une structure, en fonction de ce qui serait plus efficace.
Y aurait-il un avantage à utiliser un dictionnaire simultané? Y a-t-il un autre moyen qui est plus thread-safe?
J'utilise actuellement ThreadPool.QueueUserWorkItem
. Je ne sais pas si cela utilise un nouveau fil pour chaque élément. Sinon, je pourrais aussi le définir en fonction du contexte.
Update: Selon Classe ThreadPool - MSDN , il réutilise les threads. Et cela ne supprime pas les données de thread.
Lorsque le pool de threads réutilise un thread, il n'efface pas les données du stockage local du thread ou des champs marqués de l'attribut ThreadStaticAttribute. Par conséquent, lorsqu'une méthode examine le stockage local du thread ou les champs marqués avec l'attribut ThreadStaticAttribute, les valeurs trouvées peuvent être laissées par une utilisation antérieure du thread de pool de threads.
Une solution consisterait à utiliser un champ statique public avec l'attribut ThreadStatic
:
[ThreadStatic]
public static int ThreadSpecificStaticValue;
Un champ statique marqué avec ThreadStaticAttribute n'est pas partagé entre les threads . Chaque thread en cours 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 Accédé sur un autre thread, il contiendra une valeur différente.
Vous pouvez utiliser le mécanisme de stockage intégré de la classe de 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:
Cela fonctionnera également avec les threads créés par le pool de threads.
Pourquoi voulez-vous créer un serveur HTTP, utilisez SignalR , semble bizarre mais répondez-y
Si votre serveur Web est basé sur une instance, pourquoi ne pas conserver toutes les données requises? Si chaque instance est verrouillée sur un certain thread, il ne devrait y avoir aucun problème.