Sự khác biệt giữa Invoke và DynamicInvoke trong các đại biểu là gì? Xin vui lòng cho tôi một số ví dụ mã giải thích sự khác biệt giữa hai phương thức đó.
Sự khác biệt giữa Invoke và DynamicInvoke trong các đại biểu là gì? Xin vui lòng cho tôi một số ví dụ mã giải thích sự khác biệt giữa hai phương thức đó.
Câu trả lời:
Khi bạn có một thể hiện đại biểu, bạn có thể biết loại chính xác hoặc bạn có thể biết rằng đó là một Delegate
. Nếu bạn biết loại chính xác, bạn có thể sử dụng Invoke
, rất nhanh - mọi thứ đã được xác thực trước. Ví dụ:
Func<int,int> twice = x => x * 2;
int i = 3;
int j = twice.Invoke(i);
// or just:
int j = twice(i);
Tuy nhiên! Nếu bạn chỉ biết rằng nó Delegate
phải giải quyết các tham số vv một cách thủ công - điều này có thể liên quan đến việc bỏ hộp, v.v. - rất nhiều sự phản ánh đang diễn ra. Ví dụ:
Delegate slowTwice = twice; // this is still the same delegate instance
object[] args = { i };
object result = slowTwice.DynamicInvoke(args);
Lưu ý Tôi đã viết args
tay dài để làm rõ rằng có object[]
liên quan. Có rất nhiều chi phí phụ ở đây:
MethodInfo
Về cơ bản, tránh DynamicInvoke
khi nào bạn có thể. Invoke
luôn luôn thích hợp hơn, trừ khi tất cả những gì bạn có là a Delegate
và an object[]
.
Để so sánh hiệu suất, phần sau trong chế độ phát hành bên ngoài trình gỡ lỗi (exe console) in:
Invoke: 19ms
DynamicInvoke: 3813ms
Mã số:
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
. Tại sao bạn so sánh họ nhiều hơn 1 cuộc gọi? Và tại sao cái thứ nhất mất nhiều thời gian hơn chức năng gọi thứ hai?