Я предполагаю, что у вас есть события, представленные в вашем классе, и вы хотите, чтобы обработчики событий выполнялись в потоке пользовательского интерфейса.Я полагаю, у вас может быть обратный вызов, который также указывает вызывающая сторона.В любом случае шаблон, который я опишу ниже, будет работать в обоих случаях
Один из способов сделать это состоит в том, чтобы ваш класс принял экземпляр ISynchronizeInvoke
.Экземпляры Form
и Control
реализуют этот интерфейс, поэтому можно использовать ссылку на один из них.Можно заключить соглашение, что если экземпляр не указан, то обработчики событий, выполняемые путем вызова событий в вашем классе, будут выполняться в рабочем потоке вместо потока, в котором размещается экземпляр ISynchronizeInvoke
(обычно это форма или элемент управления).*
Public Class YourClass
Private m_SynchronizingObject As ISynchronizeInvoke = Nothing
Public Sub New(ByVal synchronizingObject As ISynchronizeInvoke)
m_SynchronizingObject = synchronizingObject
End Sub
Public Property SynchronizingObject As ISynchronizeInvoke
Get
Return m_SynchronizingObject
End Get
Set(ByVal value As ISynchronizeInvoke)
m_SynchronizingObject = value
End Set
End Property
Private Sub SomeMethodExecutingOnWorkerThread()
RaiseSomeEvent()
End
Private Sub RaiseSomeEvent()
If Not SychronizingObject Is Nothing AndAlso SynchronizingObject.InvokeRequired Then
SynchronizingObject.Invoke(New MethodInvoker(AddressOf RaiseSomeEvent)
End If
RaiseEvent SomeEvent
End Sub
End Class
Первое, на что нужно обратить внимание, это то, что вам не нужно указывать синхронизирующий объект.Это означает, что вам не нужно иметь ссылку Form
или Control
.Если он не указан, то SomeEvent
будет вызван в рабочем потоке.Это тот же шаблон, который используется в классе System.Timers.Timer
.