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.
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);
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