简体   繁体   English

.NET背景工作者在前景中看不到COM对象

[英].NET Background Workers can't see COM Objects in the Foreground

We are in the process of switching from one Mainframe 3270 client to another -- Attachmate Reflection to Bluezone. 我们正在从一个大型机3270客户端切换到另一个-Attachmate Reflection到Bluezone。 Reflection had a nice .NET API, but the only way to access Bluezone is through COM. Reflection有一个不错的.NET API,但是访问Bluezone的唯一方法是通过COM。

I have a common class in the solution that represents either a Reflection or a Bluezone object, and it grabs the existing client, whatever it happens to be, and communicates with it. 我在解决方案中有一个通用类,表示一个Reflection或Bluezone对象,它抓住了现有的客户端,无论碰巧是什么,并与之通信。

For the most part, everything is working fine. 在大多数情况下,一切正常。 When I access the Bluezone COM object through any of the projects, it functions just like Reflection. 当我通过任何项目访问Bluezone COM对象时,其功能都与反射相同。

The problem appears to be when I access the Bluezone object within a background worker. 问题出在我在后台工作程序中访问Bluezone对象时。 The background worker doesn't appear to be able to see the COM object on the main thread. 后台工作程序似乎无法在主线程上看到COM对象。

When evaluating the COM object in debug mode, all of the properties show in error with the "The function evaluation requires all threads to run" error. 在调试模式下评估COM对象时,所有属性均显示错误,并出现“函数评估要求所有线程都运行”错误。

在此处输入图片说明

I know it's a long shot, but does anyone know of a way to manage this so I can access a foreground COM object within a background thread? 我知道这是一个远景,但是没有人知道一种管理此方法的方法,以便可以在后台线程中访问前台COM对象吗?

I've worked with the vendor on numerous issues, and they have been fantastic, but I have the feeling this may be a .NET/COM thing. 我曾与供应商合作处理过许多问题,这些问题很棒,但是我感觉这可能是.NET / COM问题。

My last resort is to remove all of the background workers and make the users deal with the screen freeze, but I'd really hate to do that. 我的最后一招是删除所有后台工作人员,并让用户处理屏幕冻结,但我真的很讨厌这样做。 My other option would be a to instantiate the COM object within the background worker, but there is a cost associated with this action. 我的另一种选择是在后台工作程序中实例化COM对象,但是与此操作相关的成本很高。 I tried to Marshal.GetActiveObject("") , but either it doesn't work or I don't know the right name of the application. 我尝试使用Marshal.GetActiveObject("") ,但是它不起作用或者我不知道应用程序的正确名称。

If anyone has had similar experiences with COM and background workers, I would welcome any insight. 如果有人在COM和后台工作人员上有过类似的经历,我将欢迎您提供任何见解。

This is very much by design for COM components. 对于COM组件,这在很大程度上是设计使然。 Very unlike .NET classes, COM keeps code thread-safe if the component tells COM that it doesn't support threading. 与.NET类非常不同,如果组件告诉COM它不支持线程,则COM使代码保持线程安全。 Configured by the ThreadingModel registry key. 由ThreadingModel注册表项配置。 And COM automatically ensures that this requirement is met by automatically marshaling the call, the equivalent of Invoke() in the .NET Framework. COM通过自动封送调用(等效于.NET Framework中的Invoke())来自动确保满足此要求。

So even though you make calls from your BackgroundWorker's DoWork() event handler, those calls don't run on the worker thread, they execute on the thread that the object was created on. 因此,即使您从BackgroundWorker的DoWork()事件处理程序进行调用,这些调用也不会在辅助线程上运行,而是在创建对象的线程上执行。 If necessary an STA thread that COM creates. 如有必要,COM创建的STA线程。

The debugger knows this, it can "see" them just fine, it can tell that any watch expression is not going to be able to execute. 调试器知道这一点,它可以很好地“看到”它们,它可以告诉任何watch表达式都无法执行。 Since it has frozen all the threads in the process, except for the debugger thread. 由于它冻结了进程中的所有线程,调试器线程除外。 So no can do, the message reminds you. 消息提示您,所以无能为力。

Just a debugging artifact. 只是调试工件。 Maybe more, your BGW probably isn't very efficient or still causes the UI thread to hang. 也许更多,您的BGW可能效率不高,或者仍然导致UI线程挂起。 Check this post for code that creates a COM-friendly thread. 检查此帖子以获取创建COM友好线程的代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM