COM-объект - Threading - .net - PullRequest
5 голосов
/ 21 марта 2011

Есть ли способ выполнить метод объекта com внутри совершенно нового потока, не привязанного к основному потоку?Я попытался использовать backgrounWorker, и даже используя новый поток, выполнив Dim thr as new Thread(AddressOf blah), и ни одна из них не работает.Я нигде не ссылаюсь на COM-объект, кроме как внутри многопоточной функции "blah" или метода DoWork backgroundWorker's, но мой основной интерфейс пользователя по-прежнему блокируется при попытке обработать вызываемые мной методы COM-объекта.

Я действительноМне нужно, чтобы это выполняло методы из объекта com в отдельном потоке, потому что это вызывает блокировку всего моего приложения.

Ниже приведен пример моего потока, в котором используется метод "DoWork".Та же самая логика может быть использована для фонового работника

Public Sub Reconnect_Scanner() Implements Scanners.Reconnect_Scanner

    'Do our request on a new thread
    Dim thread As New System.Threading.Thread(AddressOf Connect)
    thread.SetApartmentState(Threading.ApartmentState.STA)
    thread.Start()


End Sub

Public Sub Connect()

    'Get a new instance of our scanner
    Dim scanner As New OposScanner_CCO.OPOSScanner

    'Loop until scanner is opened 
    Do
        Debug.Print("looking for scanner")
        'If we find the device, exit do
        Dim openId As Integer = scanner.Open("Honeywell")
        If openId = 0 Then Exit Do

        'Sleep 1 second 
        System.Threading.Thread.Sleep(250)

    Loop

End Sub

Даже если это должно выполняться в совершенно новом потоке, как только он выполнит scanner.open, мой основной поток блокируется, пока он не завершится.

Я ценю любую помощь.

Ответы [ 2 ]

6 голосов
/ 21 марта 2011

COM заботится о требованиях потоков к объектам, опубликованным в реестре с помощью раздела реестра ThreadingModel.Ваша, очевидно, «квартира», которая заставляет COM заботиться о безопасности потоков от имени объекта.Это очень распространено.И да, если вы создали его в потоке пользовательского интерфейса, то COM перенаправляет вызов из вашего рабочего потока обратно в поток пользовательского интерфейса.

Чтобы обойти это, вам нужно создать отдельный поток STA, чтобы передать объектдругой потокобезопасный дом.Это требует создания потока, вызова его метода SetApartmentState (), чтобы сделать его STA, и вызова Application.Run () для запуска цикла сообщений.С этим трудно справиться, потому что вы теряете контроль, вам нужно, чтобы Form, Timer или Control.BeginInvoke () генерировали события, позволяющие вам использовать методы объекта.Это все довольно неприятно, курсор в виде песочных часов был популярен в старину.

0 голосов
/ 03 мая 2012

Создайте COM-компоненты в рабочем потоке, чтобы ваши COM-методы не переходили в основной поток пользовательского интерфейса.

...