2012-10-12 108 views

Respuesta

160

Cuando tiene una instancia de delegado, puede saber el tipo exacto, o simplemente puede saber que es un Delegate. Si conoce el tipo exacto, puede usar Invoke, que es muy rápido - todo ya está previamente validado. Por ejemplo:

Func<int,int> twice = x => x * 2; 
int i = 3; 
int j = twice.Invoke(i); 
// or just: 
int j = twice(i); 

¡Sin embargo! Si simplemente sabe que es Delegate, tiene que resolver los parámetros, etc. manualmente, esto podría implicar el desempaquetado, etc., se está produciendo una gran cantidad de reflexión. Por ejemplo:

Delegate slowTwice = twice; // this is still the same delegate instance 
object[] args = { i }; 
object result = slowTwice.DynamicInvoke(args); 

Nota He escrito el args larga mano para que quede claro que un object[] está involucrado. Hay un montón de gastos adicionales aquí:

  • la matriz
  • validar los argumentos pasados ​​son un "ajuste" para el actual MethodInfo
  • unboxing etc., según sea necesario
  • reflexión invocar
  • entonces el la persona que llama necesita hacer algo para procesar el valor de retorno

Básicamente, evite DynamicInvoke siempre Tu puedes. Invoke siempre es preferible, a menos que todo lo que tiene es Delegate y object[].

Para una comparación de rendimiento, el siguiente en modo de lanzamiento fuera del depurador (un exe consola) impresiones:

Invoke: 19ms 
DynamicInvoke: 3813ms 

Código:

Func<int,int> twice = x => x * 2; 
const int LOOP = 5000000; // 5M 
var watch = Stopwatch.StartNew(); 
for (int i = 0; i < LOOP; i++) 
{ 
    twice.Invoke(3); 
} 
watch.Stop(); 
Console.WriteLine("Invoke: {0}ms", watch.ElapsedMilliseconds); 
watch = Stopwatch.StartNew(); 
for (int i = 0; i < LOOP; i++) 
{ 
    twice.DynamicInvoke(3); 
} 
watch.Stop(); 
Console.WriteLine("DynamicInvoke: {0}ms", watch.ElapsedMilliseconds); 
+3

¿Quiere decir que en el caso del uso de la DynamicInvoke compilador produce más código IL para manejar la invocación de delegado? – testCoder

+1

@testCoder no, usará la reflexión –

+2

Gracias, explicación muy completa. – testCoder