Diferencia entre Invoke y DynamicInvoke


¿Cuál es la diferencia entre Invoke y DynamicInvoke en delegados? Por favor, dame algún ejemplo de código que explique la diferencia entre esos dos métodos.

Author: John Saunders, 2012-10-12

1 answers

Cuando tiene una instancia delegada, 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á pre-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 solo sabe que es Delegate, tiene que resolver los parámetros, etc. manualmente - esto podría implicar unboxing, etc. - se está produciendo una gran 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 la args mano larga para dejar claro que un object[] está involucrado. Hay un montón de costos adicionales aquí:

  • el array
  • validar los argumentos pasados son un "ajuste" para el MethodInfo
  • unboxing etc. según sea necesario
  • reflexión-invocar
  • entonces el llamante necesita hacer algo para procesar el valor devuelto

Básicamente, evita DynamicInvoke cuando puedas. Invoke siempre es preferible, a menos que todo lo que tengas sea un Delegate y un object[].

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

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);
 174
Author: Marc Gravell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-12 11:49:37