Qual è la differenza tra Invoke e DynamicInvoke nei delegati? Per favore, dammi qualche esempio di codice che spieghi la differenza tra questi due metodi.Differenza tra Invoke e DynamicInvoke
risposta
Quando si dispone di un'istanza delegata, è possibile conoscere il tipo esatto oppure si potrebbe semplicemente sapere che è uno Delegate
. Se si conosce il tipo esatto, è possibile utilizzare Invoke
, che è molto veloce - tutto è già pre-convalidato. Ad esempio:
Func<int,int> twice = x => x * 2;
int i = 3;
int j = twice.Invoke(i);
// or just:
int j = twice(i);
Tuttavia! Se sai solo che è Delegate
, deve risolvere manualmente i parametri etc - questo potrebbe comportare unboxing, ecc. - si sta riflettendo molto. Per esempio:
Delegate slowTwice = twice; // this is still the same delegate instance
object[] args = { i };
object result = slowTwice.DynamicInvoke(args);
nota che ho scritto la lunga mano args
mettere in chiaro che un object[]
è coinvolto. Ci sono un sacco di costi aggiuntivi qui:
- matrice
- convalidare gli argomenti passati sono un "fit" per l'attuale
MethodInfo
- unboxing ecc come necessario
- riflessione-richiamare
- poi il il chiamante deve fare qualcosa per elaborare il valore di ritorno
In pratica, evitare DynamicInvoke
ogni volta y puoi. Invoke
è sempre preferibile, a meno che tutto quello che hai è uno Delegate
e uno object[]
.
Per un confronto delle prestazioni, il seguente nella modalità di rilascio al di fuori del debugger (un exe console) stampe:
Invoke: 19ms
DynamicInvoke: 3813ms
Codice:
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);
- 1. Differenza tra Execute, Submit e Invoke() in un ForkJoinPool
- 2. Invoke e BeginInvoke
- 3. Differenza tra $ # e $ {# @}
- 4. qual è la differenza di invoke-virtual e invoke-direct in Android
- 5. Differenza tra il metodo di sottolineatura js _.each e il metodo _.invoke
- 6. La differenza tra $ * e $ @
- 7. Differenza tra. e #
- 8. MySQL: Differenza tra ",", "e"
- 9. Differenza tra "o" e "||"
- 10. Differenza tra unwrapObservable e()
- 11. Differenza tra oggetto e *?
- 12. Differenza tra "**/* /" e "** /"?
- 13. Differenza tra jquery e $
- 14. CMake: differenza tra $ {} e "$ {}"
- 15. Differenza tra ". +" E ". +?"
- 16. VBA: Differenza tra & e +
- 17. Differenza tra numpy.logical_and e &
- 18. Differenza tra | = e^= css
- 19. Differenza tra `% in%` e `` ==
- 20. Differenza tra IntPtr e UIntPtr
- 21. Differenza tra Dizionario e Hashtable
- 22. Differenza tra SCM e SVN
- 23. differenza tra RDLC e SSRS
- 24. Differenza tra REMOTE_HOST e REMOTE_ADDR
- 25. Differenza tra "\ n" e Environment.NewLine
- 26. Differenza tra QSharedPointer e QSharedDataPointer?
- 27. Differenza tra toFixed() e toPrecision()?
- 28. Differenza tra strncpy e memcpy?
- 29. Differenza tra crittografia e hashing
- 30. Differenza tra Assembly.CreateInstance e Activator.CreateInstance?
Vuol dire che in caso di utilizzo del DynamicInvoke il compilatore produce più codice IL per gestire l'invocazione del delegato? – testCoder
@testCoder no, verrà utilizzata la riflessione –
Grazie, spiegazione molto completa. – testCoder