variable una guardar globales declaro declarar como application c# .net-4.0 thread-safety

una - variables global c#



Estableciendo una variable global en un hilo-C# (4)

¿Por qué quiere crear un servidor HTTP? Use SignalR , busque la respuesta más SignalR pero SignalR

Tengo un servidor HTTP que estoy escribiendo usando la escucha HTTP, y me gustaría declarar ciertas variables como accesibles desde cualquier lugar dentro de un hilo.

  • Mi clase de servidor web está basada en instancia, por lo que realmente no puedo usar una variable estática.
  • Podría usar una variable de instancia ya que todo el código está en una clase, pero ... No lo sé.

Pensé en usar un diccionario: Dictionary</*[type of Thread ID here]*/,ThreadData> , pero me preocupa que pueda haber problemas con los subprocesos. ThreadData probablemente sería una instancia de clase, pero podría usar una estructura, dependiendo de cuál sería más eficiente.

  • Si yo tecleara el diccionario con los ID de subprocesos y lo programara de modo que un solo subproceso solicitara su propia entrada en el diccionario, ¿habría algún problema relacionado con el subproceso al acceder al diccionario?
  • Cada hilo agregaría su propia entrada. ¿Tendré que bloquear el diccionario mientras agrego nuevos elementos de hilo? Si es así, ¿podré usar un objeto de bloqueo separado para permitir que los hilos accedan a sus propios datos mientras tanto?

¿Habría una ventaja de usar un diccionario concurrente? ¿Hay alguna otra forma que sea más segura para subprocesos?

Actualmente estoy usando ThreadPool.QueueUserWorkItem . No estoy seguro de que esto use un nuevo hilo para cada elemento. Si no, entonces también podría ser clave para el contexto.

Actualización: Según la clase ThreadPool - MSDN , reutiliza los hilos. Y no borra los datos del hilo.

Cuando el grupo de subprocesos reutiliza un subproceso, no borra los datos en el almacenamiento local de subprocesos o en los campos que están marcados con el atributo ThreadStaticAttribute. Por lo tanto, cuando un método examina el almacenamiento local de los subprocesos o los campos que están marcados con el atributo ThreadStaticAttribute, los valores que encuentre podrían quedar fuera de un uso anterior del subproceso del grupo de subprocesos.


Podría usar el mecanismo de almacenamiento incorporado de la clase de subproceso:

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

Salida de muestra:

Eso también funcionará con los hilos generados por el conjunto de hilos.


Si su servidor web está basado en instancias, ¿por qué no mantener todos los datos requeridos allí? Si cada instancia está bloqueada en un determinado hilo, no debería haber ningún problema.


Una solución sería utilizar un campo estático público , con el atributo ThreadStatic :

[ThreadStatic] public static int ThreadSpecificStaticValue;

Un campo estático marcado con ThreadStaticAttribute no se comparte entre subprocesos. Cada subproceso en ejecución tiene una instancia separada del campo, y establece y obtiene valores de forma independiente para ese campo. Si se accede al campo en un hilo diferente, contendrá un valor diferente.