123 votes

Différence entre Invoke et DynamicInvoke

Quelle est la différence entre Invoke et DynamicInvoke dans les délégués ? Veuillez me donner un exemple de code qui explique la différence entre ces deux méthodes.

Merci.

200voto

Marc Gravell Points 482669

Lorsque vous avez une instance de délégué, vous pouvez connaître le type exact, ou vous pouvez simplement savoir qu'il s'agit d'une Delegate . Si vous connaissez le type exact, vous pouvez utiliser Invoke qui est très rapide - tout est déjà pré-validé. Par exemple :

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

Cependant ! Si vous savez simplement que c'est Delegate il doit résoudre les paramètres, etc. manuellement, ce qui peut impliquer le déballage, etc. Par exemple :

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

Notez que j'ai écrit le args longue main pour préciser qu'un object[] est impliqué. Il y a beaucoup de coûts supplémentaires :

  • l'éventail
  • en validant que les arguments passés sont adaptés à l'objectif réel de l'opération. MethodInfo
  • déballage, etc., si nécessaire
  • réflexion-invoquer
  • alors l'appelant doit faire quelque chose pour traiter la valeur de retour

En gros, il faut éviter DynamicInvoke quand vous le pouvez. Invoke est toujours préférable, à moins que tout ce que vous avez soit un Delegate et un object[] .

Pour comparer les performances, l'exemple suivant s'imprime en mode "release" en dehors du débogueur (un exe de console) :

Invoke: 19ms
DynamicInvoke: 3813ms

Code :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X