Вы вывели свой класс из Control. Немного необычно, но если элемент управления фактически размещен в форме, вы можете использовать Me.Invoke (), чтобы упорядочить вызов. Например:
Private Delegate Sub SomethingHappenedDelegate(ByVal result As Integer)
Private Sub Work()
For i As Integer = 0 To 10
Me.Invoke(New SomethingHappenedDelegate(AddressOf SomethingHappenedThreadSafe), i)
Threading.Thread.Sleep(500)
Next
End Sub
Private Sub SomethingHappenedThreadSafe(ByVal result As Integer)
RaiseEvent SomthingHappend(result)
End Sub
Если этот объект класса на самом деле не размещен в форме, вам нужно передать ссылку на форму, чтобы он мог вызвать Invoke ():
Private mHost As Form
Public Sub New(ByVal host As Form)
mHost = host
End Sub
и используйте mHost.Invoke (). Или BeginInvoke ().
Последний трюк в книге - использовать основную форму запуска в качестве объекта синхронизации. Это не совсем безопасно, но работает в 99% случаев:
Dim main As Form = Application.OpenForms(0)
main.Invoke(New SomethingHappenedDelegate(AddressOf SomethingHappenedThreadSafe), i)
Помните, что в WF есть ошибка, которая не позволяет OpenForms () точно отслеживать открытые формы при их динамическом воссоздании.