[C#] 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, 매개 변수 등을 수동으로 해결해야합니다-이것은 unboxing을 포함 할 수 있습니다. 예를 들면 다음과 같습니다.

Delegate slowTwice = twice; // this is still the same delegate instance
object[] args = { i };
object result = slowTwice.DynamicInvoke(args);

참고 사항 이 포함되어 args있음을 분명히하기 위해 긴 손을 썼습니다 object[]. 여기에 많은 추가 비용이 있습니다 :

  • 배열
  • 전달 된 인수의 유효성을 검사하는 것이 실제에 “적합한” MethodInfo
  • 필요에 따라 개봉 등
  • 반사 호출
  • 호출자는 반환 값을 처리하기 위해 무언가를해야합니다.

기본적으로 가능 DynamicInvoke하면 항상 피하십시오 . Invoke모든 것이 a Delegate및 a가 아닌 한 항상 선호 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);


답변