c# - ¿Debería usarse ConditionalWeakTable<TKey, TValue> para propósitos que no sean de compilación?
garbage-collection clr (1)
Recientemente he encontrado la clase ConditionalWeakTable<TKey,TValue>
en mi búsqueda de un IDictionary
que usa referencias débiles, como se sugiere en las respuestas here y here .
Hay un artículo definitivo de MSDN que introdujo la clase y que dice:
Puede encontrar la clase ... en el espacio de nombres System.Runtime.CompilerServices. Está en CompilerServices porque no es un tipo de diccionario de propósito general: pretendemos que solo lo utilicen los escritores de compiladores.
y luego otra vez:
... la tabla débil condicional no pretende ser una colección de propósito general ... Pero si está escribiendo un lenguaje .NET propio y necesita exponer la capacidad de adjuntar propiedades a objetos, definitivamente debería mirar la Condicional Mesa débil.
De acuerdo con esto, la descripción de la entrada de MSDN de la clase dice:
Permite a los compiladores adjuntar dinámicamente campos de objetos a objetos gestionados.
Así que, obviamente, se creó originalmente con un propósito muy específico: ayudar al DLR, y el System.Runtime.CompilerServices
nombres System.Runtime.CompilerServices
incorpora. Pero parece haber encontrado un uso mucho más amplio que eso, incluso dentro del CLR. Si busco referencias de ConditionalWeakTable<TKey,TValue> en ILSpy , por ejemplo, puedo ver que se usa en la clase MEF CatalogExportProvider
y en la clase interna WPF DataGridHelper
, entre otras.
Mi pregunta es si está bien usar ConditionalWeakTable<TKey,TValue> fuera de las herramientas de escritura y lenguaje del compilador, y si existe algún riesgo al hacerlo en términos de incurrir en gastos generales adicionales o de que la implementación cambie significativamente en las futuras versiones de .NET. (O debería evitarse y se debería usar una implementación personalizada como esta ).
También hay más información here , here y here sobre cómo ConditionalWeakTable<TKey,TValue> utiliza una implementación CLR oculta de ephemerons (a través de System.Runtime.Compiler.Services. DependentHandle
) para tratar el problema de los ciclos entre claves y valores, y cómo no se puede lograr fácilmente de manera personalizada.
No veo nada de malo con el uso de ConditionalWeakTable
. Si necesitas efemerones, prácticamente no tienes otra opción.
No creo que las futuras versiones de .NET sean un problema, incluso si solo los compiladores usarían esta clase, Microsoft todavía no podría cambiarla sin romper la compatibilidad con los binarios existentes.
En cuanto a los gastos generales, ciertamente habrá gastos generales en comparación con un diccionario normal. Es probable que tener muchos DependentHandle
sea costoso de manera similar a la cantidad de WeakReference
son más caras que las referencias normales (el GC tiene que hacer un trabajo adicional para escanearlos para ver si necesitan ser anulados). Pero eso no es un problema a menos que tenga muchos (varios millones) de entradas.