COM对象 - 线程 - .net

时间:2011-03-21 20:23:37

标签: .net multithreading com backgroundworker

有没有办法在一个全新的线程中执行一个com对象的方法,而不是附加到主线程?我尝试过使用backgrounWorker,甚至通过Dim thr as new Thread(AddressOf blah)使用新线程,但都没有工作。我没有在任何地方引用COM对象,而是在线程函数“blah”或backgroundWorker的DoWork方法中,但是当我尝试处理我调用的COM对象的方法时,我的主UI仍然锁定。

我真的需要让它在一个单独的线程中执行来自com对象的方法,因为它导致我的整个应用程序被锁定。

下面是我使用“DoWork”方法的Thread的示例。可以为后台工作者采用相同的逻辑

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。打开我的主线程直到它完成。

我感谢任何帮助。

2 个答案:

答案 0 :(得分:6)

COM负责处理ThreadingModel注册表项在注册表中发布的对象的线程要求。你的显然是“公寓”,这使得COM代表对象处理线程安全。这很常见。是的,如果你在UI线程上创建了它,那么COM将你的工作线程的调用编组回UI线程。

要绕过它,您必须创建一个单独的STA线程,以便为该对象提供另一个线程安全的主页。这需要创建一个Thread,调用它的SetApartmentState()方法使其成为STA并调用Application.Run()来运行消息循环。这本身很难处理,因为你失去控制,你需要一个Form或Timer或Control.BeginInvoke()来生成让你使用对象方法的事件。这一切都非常不愉快,沙漏光标在过去很受欢迎。

答案 1 :(得分:0)

在工作线程中创建COM组件,这样您的COM方法就不会被marhshalled到主UI线程。