El delegado no necesita ser fijado. Un objeto administrado es anclado si no puede ser movido por el recolector de basura. Si la información de clasificación es correcta, la capa de clasificación garantizará que se pase un puntero a algo inmóvil.
Sin embargo, el comentario anterior en el que sugiere que una variable local puede mantener al delegado con vida indica un malentendido de la duración de la variable. Lo remito a la especificación, que dice:
La vida útil real de una variable local depende de la implementación. Por ejemplo, un compilador puede determinar estáticamente que una variable local en un bloque solo se usa para una pequeña porción de ese bloque. Usando este análisis, el compilador podría generar código que da como resultado que el almacenamiento de la variable tenga una vida más corta que su bloque contenedor. El almacenamiento contemplada por una variable de referencia local se recupera independientemente del curso de la vida de esa variable de referencia local
En otras palabras, si usted dice:
void M()
{
Foo foo = GetAFoo();
UnmanagedLibrary.DoSomethingToFoo(foo);
}
continuación, se permite decir la fluctuación " ya sabes, veo que ningún código administrado usa foo nuevamente en el momento después de invocar la llamada no administrada, por lo que puedo reclamar agresivamente el almacenamiento de ese objeto desde otro subproceso en ese momento ". Lo que significa que la llamada no administrada puede estar funcionando en el objeto cuando de repente se desasigna en otro hilo.
Esto es particularmente desagradable si Foo tiene un destructor. El código de finalización posiblemente se ejecutará en otro subproceso mientras el objeto esté en uso por la biblioteca no administrada, y solo Dios sabe qué tipo de desastre causará.
En esta circunstancia debe usar KeepAlive para mantener vivo el objeto gestionado. No confíe en una variable local; las variables locales están específicamente documentadas como no garantizadas para mantener las cosas con vida.
Ver http://msdn.microsoft.com/en-us/library/system.gc.keepalive.aspx para más detalles.
Si el método anónimo es una variable local ¿se considera "activo" mientras CopyFileEx no haya regresado? – SpeksETC
estoy seguro de que es – sehe
@sehe, @SpeksETC: Muy cierto, ¿verdad? ¿Dónde exactamente en la especificación dice eso? Mi copia de la especificación dice lo contrario, es decir, "* el compilador puede generar código que da como resultado que el almacenamiento de la variable tenga una vida útil más corta que su bloque *." –