usar programacion porque net los funcionan eventos ejemplo delegate delegados delegado concepto como delegates virtual override invoke begininvoke

delegates - programacion - invoke en vb net



Invoke() y BeginInvoke() se comportan de manera diferente al ejecutar un método sobrescribible a través de un delegado (3)

¿Alguien puede decirme por qué este código se comporta de la manera en que lo hace? Ver comentarios incrustados en el código ...

¿Me estoy perdiendo algo realmente obvio aquí?

using System; namespace ConsoleApplication3 { public class Program { static void Main(string[] args) { var c = new MyChild(); c.X(); Console.ReadLine(); } } public class MyParent { public virtual void X() { Console.WriteLine("Executing MyParent"); } } delegate void MyDelegate(); public class MyChild : MyParent { public override void X() { Console.WriteLine("Executing MyChild"); MyDelegate md = base.X; // The following two calls look like they should behave the same, // but they behave differently! // Why does Invoke() call the base class as expected here... md.Invoke(); // ... and yet BeginInvoke() performs a recursive call within // this child class and not call the base class? md.BeginInvoke(CallBack, null); } public void CallBack(IAsyncResult iAsyncResult) { return; } } }


Aún no tengo una respuesta, pero tengo lo que creo que es un programa un poco más claro para demostrar la rareza:

using System; delegate void MyDelegate(); public class Program { static void Main(string[] args) { var c = new MyChild(); c.DisplayOddity(); Console.ReadLine(); } } public class MyParent { public virtual void X() { Console.WriteLine("Executing MyParent.X"); } } public class MyChild : MyParent { public void DisplayOddity() { MyDelegate md = base.X; Console.WriteLine("Calling Invoke()"); md.Invoke(); // Executes base method... fair enough Console.WriteLine("Calling BeginInvoke()"); md.BeginInvoke(null, null); // Executes overridden method! } public override void X() { Console.WriteLine("Executing MyChild.X"); } }

Esto no implica ninguna llamada recursiva. El resultado sigue siendo la misma rareza:

Calling Invoke() Executing MyParent.X Calling BeginInvoke() Executing MyChild.X

(Si acepta que esta es una reproducción más simple, siéntase libre de reemplazar el código en la pregunta original y lo eliminaré de mi respuesta :)

Para ser honesto, esto parece un error para mí. Excavaré un poco más.


Tal vez no es la respuesta que está buscando, pero parece que funciona:

ThreadPool.QueueUserWorkItem(x => md());

o

new Thread(() => md()).Start();

Pero tendrá que hacer su propia contabilidad :(


Mientras Delegate.Invoke llama directamente al método de delegado, Delegate.BeginInvoke usa internamente ThreadPool.QueueUserWorkItem (). md.Invoke () solo pudo llamar a base.X porque los métodos de una clase base son accesibles dentro de la clase derivada a través de la palabra clave base. Como el delegado iniciado por el grupo de subprocesos es externo a su clase, la referencia a su método X está sujeta a sobrecarga, al igual que el código siguiente.

public class Program { static void Main(string[] args) { MyChild a = new MyChild(); MyDelegate ma = new MyDelegate(a.X); MyParent b = new MyChild(); MyDelegate mb = new MyDelegate(b.X); ma.Invoke(); mb.Invoke(); ma.BeginInvoke(CallBack, null); mb.BeginInvoke(CallBack, null); //all four calls call derived MyChild.X Console.ReadLine(); } public static void CallBack(IAsyncResult iAsyncResult) { return; } }

Depure en el código de .NET Framework: http://blogs.msdn.com/sburke/archive/2008/01/16/configuring-visual-studio-to-debug-net-framework-source-code.aspx