What is the difference between Invoke and DynamicInvoke in delegates? Please give me some code example which explain difference between that two methods.
DynamicInvoke is used when you don't know the type of the delegate at compile time. It resolves the parameters using reflection and thus it's slower than Invoke. You should always use Invoke over DynamicInvoke when you can. Calling a delegate "directly" and using the Invoke method are the same.
Create the delegate and matching procedures Create a delegate named MySubDelegate . Declare a class that contains a method with the same signature as the delegate. Define a method that creates an instance of the delegate and invokes the method associated with the delegate by calling the built-in Invoke method.
A delegate is a type that represents references to methods with a particular parameter list and return type. When you instantiate a delegate, you can associate its instance with any method with a compatible signature and return type. You can invoke (or call) the method through the delegate instance.
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:
MethodInfo
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With