147

デリゲートのInvokeとDynamicInvokeの違いは何ですか?その2つの方法の違いを説明するコード例を教えてください。

4

1 に答える 1

226

デリゲート インスタンスがある場合、正確な型がわかっている場合もあれば、それが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);

argsan が含まれていることを明確にするために、長い手形を書いたことに注意してくださいobject[]。ここには多くの追加費用があります。

  • 配列
  • 渡された引数が実際のMethodInfo
  • 必要に応じて開梱など
  • リフレクション呼び出し
  • 次に、呼び出し元は戻り値を処理するために何かをする必要があります

基本的に、DynamicInvokeできる限り避けてください。あなたが持っているのが aと anInvokeだけでない限り、常に望ましいです。Delegateobject[]

パフォーマンスの比較のために、デバッガー (コンソール 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);
于 2012-10-12T11:49:37.703 に答える