Estoy tratando de sacar los detalles de un verdadero WeakKeyedDictionary<,>
para C# ... pero me encuentro con dificultades.¿Es posible crear un diccionario de clave débil en C#?
Me doy cuenta de que esta es una tarea no trivial, pero la aparente incapacidad para declarar un WeakKeyedKeyValuePair<,>
(donde el GC solo sigue la referencia de valor si la tecla es alcanzable) lo hace aparentemente imposible.
Hay dos problemas principales que veo:
Cada aplicación que he visto hasta el momento no recortar valores después de llaves se han recogido. Piénselo: una de las principales razones para utilizar dicho diccionario es evitar que se mantengan esos valores (¡no solo las claves!), Ya que son inalcanzables, pero aquí las referencias fuertes lo señalan.
Sí, agregue/elimine del Diccionario lo suficiente y eventualmente serán reemplazados, pero ¿y si no?
Sin un hipotético
WeakKeyedKeyValuePair<,>
(u otro medio para decirle al GC que solo marque el valor si la clave es alcanzable), ningún valor que haga referencia a su clave nunca se recopilará. Esto es un problema cuando se almacenan valores arbitrarios.
Problema 1 podría abordarse de una manera bastante no ideal/hacker: usar GC Notificaciones que esperar a que un GC completo para terminar, y luego ir a lo largo y podar el diccionario en otro hilo. Este con el que estoy semi-bien.
Pero el problema 2 me tiene perplejo. Me doy cuenta de que esto es contrarrestado fácilmente por un "así que no hagas eso", pero me pregunto si este problema es posible de resolver.
Buen hallazgo, más intrigante! ¿Cómo se implementa? Me pregunto? Sin saber esto, el problema se convierte en "¿es posible crear un verdadero DiluitivoVálido <,>". Voy a profundizar en el reflector y ver si puedo resolverlo ... – Mania
Qué pena, parece que depende de un .NET-magic interno "DependentHandle" para su implementación ... además ignora .GetHashCode y .Equals , convirtiéndolo en un diccionario deficiente en el mejor de los casos :(. Además, sin acceso a DependentHandle, el problema ahora se ha trasladado a la definición de un WeakValuedDictionary <,>. Supongo que esto puede ser lo más cercano que podamos ... – Mania
@Mania The DependentHandle es la implementación de CLR de [ephemerons] (http://en.wikipedia.org/wiki/Ephemeron) que es imposible de implementar sin la cooperación de GC. Debería haber sido hecho público como GCHandle. Si no te importa el truco de la reflexión, puedes activar la estática Los métodos CLR en delegados e implementar su propio DependentHandle y WeakValuedDictionary. Tenga cuidado de estudiar el origen de referencia de .NET (que es público), o use algún descompilador, ya que tiene condiciones de carrera complicadas. ns. – Zarat