COM 对象 - 线程 - .net
有没有办法在一个全新的线程中执行 com 对象的方法,而不附加到主线程?我尝试过使用 backgrounWorker,甚至通过执行 Dim thr as new Thread(AddressOf blah)
来使用新线程,但都不起作用。除了线程函数“blah”或backgroundWorker 的DoWork 方法之外,我没有在任何地方引用COM 对象,但我的主UI 在尝试处理我正在调用的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 我的主线程就会锁定直到它完成。
我很感激任何帮助。
Is there any way to execute a method of a com object inside a completely new thread, not attached to the main thread? I have tried using a backgrounWorker, and even using a new thread by doing Dim thr as new Thread(AddressOf blah)
and neither work. I am not referencing the COM object anywhere but inside the threaded function "blah" or the backgroundWorker's DoWork method, yet still my main UI locks up as it tries to process the COM object's methods I am calling.
I really need to make this execute the methods from the com object in a separate thread because it is causing my whole application to lock up.
Below is an example of my Thread that uses a method "DoWork". The same logic can be taken for a background worker
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
Even though that should be running on a completely new thread, once it does scanner.open my main thread locks up till it is complete.
I appreciate any help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
COM 负责处理由 ThreadingModel 注册表项在注册表中发布的对象的线程要求。您的显然是“公寓”,这使得 COM 代表对象负责线程安全。这很常见。是的,如果您在 UI 线程上创建它,那么 COM 会将来自工作线程的调用封送回 UI 线程。
要绕过这个问题,您必须创建一个单独的 STA 线程来为对象提供另一个线程安全的家。这需要创建一个线程,调用其 SetApartmentState() 方法使其成为 STA 并调用 Application.Run() 来运行消息循环。这本身就很难处理,因为你失去了控制,你需要一个 Form 或 Timer 或 Control.BeginInvoke() 来生成让你使用对象方法的事件。这一切都非常不愉快,沙漏光标在过去很流行。
COM takes care of the object's threading requirements as published in the registry by the ThreadingModel registry key. Yours is obviously "Apartment", which makes COM take care of thread-safety on the object's behalf. That's very common. And yes, if you created it on the UI thread then COM marshals the call from your worker thread back to the UI thread.
To bypass that, you'd have to create a separate STA thread to give the object another thread-safe home. That requires creating a Thread, calling its SetApartmentState() method to make it STA and calling Application.Run() to run a message loop. That in itself is hard to deal with because you lose control, you'll want a Form or a Timer or Control.BeginInvoke() to generate events that let you use the object's methods. This is all pretty unpleasant, an hourglass cursor was popular in the olden days.
在工作线程中创建 COM 组件,这样您的 COM 方法就不会编组到主 UI 线程。
Create the COM components in the worker thread so your COM methods won't be marhshalled to the Main UI thread.