Запуск COM-объекта в выделенном потоке - ошибка RCW
Используя Windows Forms и VB.NET, я пытаюсь создать графический интерфейс приложения, который будет взаимодействовать с объектом ActiveX/COM.
Я могу создавать и использовать COM-объект без каких-либо проблем непосредственно из формы или через класс в отдельном модуле. Однако оба этих сценария приводят к зависанию пользовательского интерфейса при вызове методов объекта.
Итак, я пытался создать отдельный поток, чтобы посвятить себя обработке COM-объекта. У меня это работает так, как я хотел, но это не кажется очень надежным. Я новичок в потоках и хотел бы некоторые альтернативные подходы (если таковые имеются).
В настоящее время я создаю поток и зацикливаюсь, чтобы оставить его открытым. Если я позволю потоку завершиться после создания объекта, любой последующий вызов метода приведет к
COM-объект, который был отделен от базового RCW, не может быть использован.
ошибка.
Вот конструктор для моего класса, который будет обрабатывать COM-объект:
Sub New()
myThread = New Thread(AddressOf ThreadLoop)
myThread.SetApartmentState(ApartmentState.STA)
myThread.Start()
End Sub
Вот основной цикл, который выполняется в потоке:
Private Sub ThreadLoop()
ComObject = New ComObject
ComObject.CreateControl()
While Not _Terminate
Application.DoEvents()
Select Case _State
Case 1
_Open()
Case 2
_Close()
Case 3 '...
Case Else
Thread.Sleep(0)
End Select
End While
'ComObject.Dispose()
myThread.Abort()
End Sub
_Terminate - логическое свойство, которое завершает цикл.
_State - это int, измененный из пользовательского интерфейса и (на основе оператора case) запускает методы, которые обрабатывают вызовы COM - т.е.
Private Sub _Open()
Try
iReturnCode = ComObject.Open()
Catch ex As Exception
iReturnCode = -1
End Try
_State = 0
RaiseEvent UpdateUI("Open", Nothing)
End Sub
Удивительно, но в настоящее время он делает именно то, что я хочу, но я не могу себе представить, что это подходящий способ справиться с этой ситуацией.
Я ищу предложения (или, возможно, насмешки) о том, как правильно поточить этот COM-объект, чтобы он не мешал моим операциям пользовательского интерфейса.
Спасибо,
bstiffler