ความแตกต่างระหว่าง 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
โดยพื้นฐานแล้วให้หลีกเลี่ยงDynamicInvoke
เมื่อคุณทำได้ Invoke
จะดีกว่าเสมอเว้นแต่สิ่งที่คุณมีคือ a 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);
Invoke: 0,0478ms, DynamicInvoke: 0,053ms
MS ทำไมคุณถึงเปรียบเทียบการโทรมากกว่า 1 ครั้ง แล้วทำไมอันแรกถึงใช้เวลานานกว่าการเรียกฟังก์ชันที่สอง?