102
代表中的Invoke和DynamicInvoke之間有什麼區別?請給我一些解釋這兩種方法之間差異的代碼示例。Invoke和DynamicInvoke之間的區別
代表中的Invoke和DynamicInvoke之間有什麼區別?請給我一些解釋這兩種方法之間差異的代碼示例。Invoke和DynamicInvoke之間的區別
當你有一個委託實例時,你可能知道確切的類型,或者你可能只知道它是一個Delegate
。如果你知道確切的類型,你可以使用Invoke
,這是非常快 - 一切都已經預先驗證。例如:
Func<int,int> twice = x => x * 2;
int i = 3;
int j = twice.Invoke(i);
// or just:
int j = twice(i);
但是!如果你只知道它是Delegate
,它必須手動解析參數等 - 這可能涉及拆箱等 - 很多反射正在進行。例如:
Delegate slowTwice = twice; // this is still the same delegate instance
object[] args = { i };
object result = slowTwice.DynamicInvoke(args);
注意我已經寫了args
長的手說清楚,一個object[]
參與。這裏有很多的額外成本:
MethodInfo
基本上,在y時應避免DynamicInvoke
你可以。 Invoke
總是更可取,除非您擁有的是Delegate
和object[]
。
對於性能比較,在釋放模式調試器的外部設置(控制檯EXE)打印:
Invoke: 19ms
DynamicInvoke: 3813ms
代碼:
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);
這是否意味着在使用的DynamicInvoke的情況下,編譯器生成更多的IL代碼來處理委託調用? – testCoder
@testCoder不,它會使用反射 –
謝謝,非常全面的解釋。 – testCoder