问题
What is the difference between Invoke and DynamicInvoke in delegates? Please give me some code example which explain difference between that two methods.
回答1:
When you have a delegate instance, you might know the exact type, or you might just know that it is a Delegate
. If you know the exact type, you can use Invoke
, which is very fast - everything is already pre-validated. For example:
Func<int,int> twice = x => x * 2;
int i = 3;
int j = twice.Invoke(i);
// or just:
int j = twice(i);
However! If you just know that it is Delegate
, it has to resolve the parameters etc manually - this might involve unboxing, etc - a lot of reflection is going on. For example:
Delegate slowTwice = twice; // this is still the same delegate instance
object[] args = { i };
object result = slowTwice.DynamicInvoke(args);
Note I've written the args
long hand to make it clear that an object[]
is involved. There are lots of extra costs here:
- the array
- validating the passed arguments are a "fit" for the actual
MethodInfo
- unboxing etc as necessary
- reflection-invoke
- then the caller needs to do something to process the return value
Basically, avoid DynamicInvoke
when-ever you can. Invoke
is always preferable, unless all you have is a Delegate
and an object[]
.
For a performance comparison, the following in release mode outside of the debugger (a console exe) prints:
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);
来源:https://stackoverflow.com/questions/12858340/difference-between-invoke-and-dynamicinvoke