2017-01-03 16 views
6

Tôi đã nhìn thấy những 2 phiên bản của mã trong khi nhìn vào mã số nhà phát triển khác:BeginInvoke có/không sử dụng MethodInvoker — nó có tạo nên sự khác biệt nào không?

1.

Me.BeginInvoke(New MethodInvoker(Sub() cbo.ShowPopup())) 

2.

Me.BeginInvoke(Sub() 
         cbo.ShowPopup() 
        End Sub) 

Are cả hai câu lệnh tương đương, hoặc là họ khác nhau theo một cách nào đó? Ngoài ra, không phải EndInvoke() cần thiết với BeginInvoke()?

Trả lời

6

Không, không có sự khác biệt chức năng giữa hai. Chỉ có một sự khác biệt thực hiện rất nhỏ, không có gì phải lo lắng. Sử dụng cú pháp bạn ưa thích cho khả năng đọc, hầu hết mọi người sẽ ưu tiên đoạn trích (2).

Một số tỷ lệ cược mà đoạn mã (1) được viết bởi một lập trình viên C#. Đối số đầu tiên của BeginInvoke là System.Delegate, là lớp cơ sở của tất cả các loại đại biểu. C# yêu cầu bạn sử dụng một loại đại biểu cụ thể, bởi vì nó là một loại ngôn ngữ rất an toàn. Nhưng VB.NET có danh tiếng (gần như) là một ngôn ngữ động và không tạo ra cùng một nhu cầu, thậm chí không có hiệu lực với Option Strict On.

Tôi khuyên bạn nên sử dụng tiện ích ildasm.exe để xem mã được tạo cho cả hai câu lệnh. Bạn sẽ thấy rằng chúng tạo ra cùng mã chính xác. Chỉ cần một sự khác biệt rất nhỏ: trình biên dịch sử dụng một loại đại biểu khác nhau. Nhất thiết là vậy, vì nó không có kiến ​​thức đặc biệt về MethodInvoker. Loại đại biểu đó được tạo tự động từ biểu thức lambda và có tên chiến thắng như VB$AnonymousDelegate_0. Điều đó có thể cung cấp trình biên dịch vừa trong thời gian ngắn hơn một chút để làm, giả sử rằng bạn sử dụng MethodInvoker một cách nhất quán và không sử dụng Ngen. Rất khó để hội đủ điều kiện, và không thể đo lường chính xác. Nó chỉ là một chi phí một lần, và không có gì phải lo lắng.

Chi tiết khác là loại an toàn, loại C# yêu cầu. Bạn có thể cố ý ngắt mã bằng cách sử dụng, ví dụ: Sub(arg As Integer) cho biểu thức lambda. Điều đó sẽ làm hỏng chương trình khi chạy vì đối số arg không khả dụng. Nếu bạn sử dụng MethodInvoker thì bạn sẽ nhận được một lỗi biên dịch. Đó là tốt hơn so với cố gắng để gỡ lỗi lỗi thời gian chạy. Nhưng có khả năng bạn sẽ thay đổi loại ủy nhiệm thành Action(Of Integer) và nó sẽ vẫn bị lỗi.

Và không, bạn không cần (và không nên) gọi EndInvoke(). Những phương pháp này không có tên rất tốt vì nó làm cho chúng trông quá giống các phương thức của một loại đại biểu. Đây là một chút sai lầm thiết kế. Tìm nitty-gritty trong this answer.

+0

Cảm ơn bạn Hans ... Điều đó rất lý giải .... và Cảm ơn Cody đã chỉnh sửa ... :) – Khan

Các vấn đề liên quan