Начните вызывать с / без использования MethodInvoker - это имеет какое-то значение?
Я видел эти 2 версии кода, глядя на код некоторых других разработчиков:
1.
Me.BeginInvoke(New MethodInvoker(Sub() cbo.ShowPopup()))
2.
Me.BeginInvoke(Sub()
cbo.ShowPopup()
End Sub)
Оба утверждения эквивалентны или в чем-то отличаются? Кроме того, не обязательно ли EndInvoke() с BeginInvoke()?
1 ответ
Нет, между ними нет функциональной разницы. Разница в реализации очень небольшая, не о чем беспокоиться. Используйте синтаксис, который вы предпочитаете для удобства чтения, большинство предпочитает сниппет (2).
Некоторые шансы, что сниппет (1) был написан программистом C#. Первый аргумент BeginInvoke это System.Delegate
, который является базовым классом всех типов делегатов. C# требует, чтобы вы использовали определенный тип делегата, потому что это очень строго типобезопасный язык. Но VB.NET имеет репутацию (почти) динамического языка и не требует того же самого, даже с Option Strict On
в результате.
Я рекомендую вам использовать утилиту ildasm.exe, чтобы посмотреть на сгенерированный код для обоих операторов. Вы увидите, что они производят точно такой же код. Одно очень маленькое отличие: компилятор использует другой тип делегата. Обязательно так, так как он не имеет специальных знаний о MethodInvoker. Этот тип делегата генерируется автоматически из лямбда-выражения и имеет странное имя, например VB$AnonymousDelegate_0
, Это могло бы немного ускорить работу компилятора точно в срок, предполагая, что вы используете MethodInvoker последовательно и не используете Ngen. Очень трудно квалифицировать и невозможно измерить точно. Это единовременная плата и не о чем беспокоиться.
Другая деталь - безопасность типов, та, которую требует C#. Вы можете намеренно нарушить код, используя, скажем, Sub(arg As Integer)
для лямбда-выражения. Это приведет к сбою программы во время выполнения, поскольку аргумент arg недоступен. Если вы используете MethodInvoker, вы получите ошибку во время компиляции. Это лучше, чем пытаться отлаживать ошибку времени выполнения. Но также вероятно, что вы измените тип делегата на Action(Of Integer)
и он все равно потерпит крах.
И нет, вам не нужно (и не нужно) вызывать EndInvoke(). Эти методы не имеют очень хороших имен, потому что они слишком похожи на методы типа делегата. Это немного ошибка дизайна. Найдите мельчайшие детали в этом ответе.