デリゲートのInvokeとDynamicInvokeの違いは何ですか?その2つの方法の違いを説明するコード例を教えてください。
質問する
50818 次
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);
args
an が含まれていることを明確にするために、長い手形を書いたことに注意してくださいobject[]
。ここには多くの追加費用があります。
- 配列
- 渡された引数が実際の
MethodInfo
- 必要に応じて開梱など
- リフレクション呼び出し
- 次に、呼び出し元は戻り値を処理するために何かをする必要があります
基本的に、DynamicInvoke
できる限り避けてください。あなたが持っているのが aと anInvoke
だけでない限り、常に望ましいです。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);
于 2012-10-12T11:49:37.703 に答える