2011-10-21 17 views
11

Tengo una biblioteca muy antigua pero muy grande que estoy considerando convertir a una biblioteca de clase C#. La biblioteca existente usa muchas variables globales almacenadas en TLS. C# no tiene un concepto real de variables globales pero una solución es usar una clase estática llamada algo así como GlobalVar y ponerlas todas en esta clase para que se pueda acceder a ellas a través de GlobalVar.xxxxxxSubproceso de almacenamiento local para C# Class Library

Sin embargo, mi pensamiento es que esto se romperá todo el código existente que se está convirtiendo como clase GlobalVar será una clase global normal y no por almacenamiento de subprocesos. ¿Hay alguna forma de obtener estos globales por hilo? es decir, ¿cuál es el equivalente de __declspec (hilo) estático en C#?

Debo añadir en este punto que odio las variables globales. Creo que a menudo son el resultado de un diseño pobre. Sin embargo, debido a las restricciones de tiempo, la primera fase es convertir la biblioteca a C# con un mínimo esfuerzo y luego la fase 2 será rediseñarlos adecuadamente.

Respuesta

14

Existen la clase ThreadLocal (introducida en 4.0) y la ThreadStaticAttribute.

El ThreadStaticAttribute se puede usar solo en los campos static. La clase ThreadLocal se puede usar en campos "normales" pero es más lenta.

Tenga en cuenta que si no controla el hilo en el que se encuentra (por ejemplo, usted es una página de ASP.NET y comienza con un hilo "aleatorio" preutilizado, o si es un hilo de un ThreadPool), entonces sus variables "thread-static" (en general, no el atributo) serán preinicializadas con los valores anteriores del hilo anterior. (ver por ejemplo A tale of two techniques: The [ThreadStatic] Attribute and System.Web.HttpContext.Current.Items)

Me estaba olvidando, existe el Thread.AllocateDataSlot que tiene "objetivos" similares a los demás.

+0

Hehe, parece que insiste en enseñarnos el idioma italiano :-) –

+0

@xanatos 'The ThreadStaticAttribute se puede usar solo en campos estáticos' no siempre es cierto. La gente puede querer declarar una variable por cada hilo por instancia –

+0

Mi italiano no es tan bueno, pero bromear, muchas gracias por la ayuda. Aunque estoy un poco preocupado por el último párrafo relacionado con el uso de ThreadPool. No creo que esto sea un problema al principio, pero es algo que podría necesitar consideración en el futuro. – Jonnster

3

Puede lograr el mismo almacenamiento local de subprocesos utilizando el atributo [ThreadStatic] o en .Net 4 utilizando la clase ThreadLocal.

[ThreadStatic]  
private static string MyThreadGlobal; 

private ThreadLocal<string> MyThreadGlobal = new ThreadLocal<string>(); 

También hay la clase CallContext pero los otros enfoques son probablemente el preferido.

3

Suponiendo que vas a utilizar .NET 4.0, usted podría tener un static ThreadLocal<ThreadLocalData> donde su clase ThreadLocalData tiene todas las variables como propiedades:

class ThreadLocalData 
{ 
    public int GlobalInt { get; set; } 
    public string GlobalString { get; set; } 
} 

class Global 
{ 
    static ThreadLocal<ThreadLocalData> _ThreadLocal = 
     new ThreadLocal<ThreadLocalData>(() => new ThreadLocalData()); 

    public static ThreadLocalData ThreadLocal 
    { 
     get { return _ThreadLocal.Value; } 
    } 
} 

A continuación, acceda a las propiedades de esta manera:

int i = Global.ThreadLocal.GlobalInt; 

Puede agregar cualquier variable global que no sea local de subprocesos como propiedades normales de la clase Global.