2010-01-15 6 views
16

Descubrí 'ThreadStaticAttribute', y tengo muchas preguntas al respecto: todas mis informaciones estáticas anteriores dependientes de hilos, se implementaron como un diccionario estático que TKey es Thread, y cuando quería acceder a ellas, usé Thread. CurrentThread y eso funciona. Pero esto requiere mantenimiento, porque si un hilo muere, tengo que eliminar la entrada correspondiente del diccionario. Y también necesito considerar la seguridad de las hebras y muchas otras cuestiones.Los campos marcados con C# ThreadStaticAttribute se liberan automáticamente cuando se corta el hilo?

Al usar ThreadStaticAttribute, todos estos asuntos parecen estar resueltos, pero necesito estar seguro de ello. Mis preguntas son: ¿necesito eliminar la instancia retenida por los campos marcados 'ThreadStaticAttribute', de alguna manera, antes de que el hilo muera? ¿Dónde se guarda la información de ese campo? Es en la instancia del objeto Thread, o algo así, para que cuando ya no se use, el recolector de basura lo descarte automáticamente? ¿Hay sanciones de rendimiento? ¿Cuáles? ¿Es más rápido que usar una colección Keyed como lo estaba haciendo?

Por favor, necesito aclaraciones sobre cómo funciona 'ThreadStaticAttribute'.

Gracias.

Respuesta

11

No, no es necesario eliminar las instancias de valores de ayuda en un campo etiquetado con ThreadStatic. El recolector de basura los recogerá automáticamente cuando los objetos rooteados ya no puedan acceder a la hebra y al objeto.

La única excepción aquí es si el valor implementa IDisposable y desea desecharlo activamente. En general, este es un problema difícil de resolver por varias razones. Es mucho más simple no tener valores que implementen IDisposable y estén en un campo ThreadStatic.

En cuanto a dónde se almacena realmente este campo, es algo irrelevante. Todo lo que necesita preocuparse es que se comportará como cualquier otro objeto en .Net. Las únicas dos diferencias de comportamiento son

  1. El campo hará referencia a un valor diferente por cada subproceso que acceda.
  2. El inicializador para el campo solo se ejecutará una vez (en la práctica, es una mala idea tener alguno).
6

Marcar una variable de miembro estática como [ThreadStatic] le dice al compilador que la asigne en el área de memoria del subproceso (por ejemplo, donde se asigna la pila del subproceso) en lugar de en el área de memoria global. Por lo tanto, cada hilo tendrá su propia copia (que se garantiza que se inicializará con el valor predeterminado para ese tipo, por ejemplo, nulo, 0, falso, etc.; no use inicializadores en línea, ya que solo lo inicializarán para un hilo)

Por lo tanto, cuando el hilo se va, también lo hace su área de memoria, liberando la referencia. Por supuesto, si es algo que necesita un desecho más inmediato (abrir cadenas de archivos, etc.) en lugar de esperar a que se recoja basura en el fondo, es posible que desee asegurarse de hacerlo antes de que el hilo salga.

Podría haber un límite en la cantidad de espacio [ThreadStatic] disponible, pero debería ser suficiente para usos sencillos. Debería ser algo más rápido que acceder a una colección con clave (y más fácilmente a prueba de subprocesos), y creo que es comparable al acceso a una variable estática normal.

Corrección: He oído desde entonces que el acceso a las variables ThreadStatic es algo más lento que el acceso a las variables estáticas normales.No estoy seguro de si realmente es más rápido que acceder a una colección con clave, pero evita los problemas de los huérfanos (que era su pregunta) y la necesidad de bloquear la seguridad de los hilos, lo que complicaría un enfoque de recolección de claves.

+1

El compilador literalmente no hace nada por el atributo 'ThreadStatic'. Está completamente manejado por el CLR – JaredPar

+0

Bien, pero tomando el "compilador" en un sentido metafórico en lugar de sentido estrictamente literal, se obtiene la idea en cuanto a cómo usar el atributo. –

Cuestiones relacionadas