Estoy utilizando un delegado que llama a un puntero de función no administrado. Esto hace que el recolector de basura la recopile antes de usarla, tal como se describe en la página CallbackOnCollectedDelegate MDA en MSDN: MSDN page for CallbackOnCollectedDelegate MDA.Definición de un delegado como un puntero a función
La resolución indica que tengo que reunir el delegado apropiado como un puntero de función no administrado. Mi reflejo inicial era utilizar:
[MarshalAs(UnmanagedType.FunctionPtr)]
public delegate void EntityCallback([MarshalAs(UnmanagedType.SysInt)] IntPtr entity);
Sin embargo, el compilador de C# no me deja Marshal un delegado, incluso si esta es la solución sugerida por MSDN. Además, la página de MSDN solo muestra un ejemplo del problema que se está lanzando, pero no de la resolución.
¿Cómo podría ordenar mi delegado como un puntero de función no administrado o evitar que se GCed?
EDIT: Como sugerí, creé una referencia de la devolución de llamada. Por lo tanto, mi código cambió de/a:
// From:
foo.SetCallback(new EntityCallback(bar));
// To:
call = new EntityCallback(bar); // Referenced in class
foo.SetCallback(call);
Ahora esto funciona, pero solo en el modo de depuración. Cuando cambio a Release, se bloquea en el mismo punto. ¿Porqué es eso?
EDIT 2: Código más completo fragmento:
public class Test
{
private EntityCallback Call;
private void Bar(System.IntPtr target)
{
...
}
public Entity Foo { get; set; }
public Test()
{
this.Foo = new Body.Sphere() { Visible = false }; // Irrelevant
this.Foo.CollisionType = 3; // Irrelevant
this.Call = new EntityCallback(this.Bar);
this.Foo.SetCallback(this.Call, EntityCallbackType.Collision);
}
}
Editado, vea mi nueva pregunta, por favor. – Lazlo
No puedo decir por el muy escaso fragmento de código cuánto tiempo estará cerca el objeto que almacena "llamada". –
Agregó un fragmento de código más completo. – Lazlo