.NET 后台工作者看不到前台的 COM 对象
.NET Background Workers can't see COM Objects in the Foreground
我们正在从一台大型机 3270 客户端切换到另一台 -- Attachmate Reflection to Bluezone。 Reflection 有一个不错的 .NET API,但访问 Bluezone 的唯一方法是通过 COM。
我在解决方案中有一个通用的 class,它表示 Reflection 或 Bluezone 对象,它会抓住现有的客户端,无论它是什么,并与之通信。
在大多数情况下,一切正常。当我通过任何项目访问 Bluezone COM 对象时,它的功能就像反射一样。
问题似乎出在我在后台工作程序中访问 Bluezone 对象时。后台工作者似乎无法在主线程上看到 COM 对象。
在调试模式下评估 COM 对象时,所有属性都显示错误 "The function evaluation requires all threads to run"。
我知道这是不可能的,但是有谁知道管理它的方法以便我可以在后台线程中访问前台 COM 对象?
我曾与供应商就许多问题进行过合作,他们非常出色,但我觉得这可能是一件 .NET/COM 事情。
我最后的办法是删除所有后台工作人员并让用户处理屏幕冻结,但我真的不想那样做。我的另一个选择是在后台工作程序中实例化 COM 对象,但此操作会产生相关成本。我试过 Marshal.GetActiveObject("")
,但要么不起作用,要么我不知道应用程序的正确名称。
如果有人对 COM 和后台工作人员有过类似的经历,我将欢迎任何见解。
这在很大程度上是为 COM 组件设计的。与 .NET 类 非常不同,如果组件告诉 COM 它不支持线程,COM 会保持代码线程安全。由 ThreadingModel 注册表项配置。 COM 通过自动封送调用自动确保满足此要求,相当于 .NET Framework 中的 Invoke()。
因此,即使您从 BackgroundWorker 的 DoWork() 事件处理程序进行调用,这些调用也不会 运行 在工作线程上执行,它们会在创建对象的线程上执行。如有必要,COM 创建的 STA 线程。
调试器知道这一点,它可以 "see" 它们就好了,它可以判断出任何 watch 表达式都无法执行。因为它冻结了进程中的 所有 线程,调试器线程除外。所以没办法,留言提醒。
调试神器而已。也许更多,您的 BGW 可能效率不高或仍然导致 UI 线程挂起。检查 this post 创建 COM 友好线程的代码。
我们正在从一台大型机 3270 客户端切换到另一台 -- Attachmate Reflection to Bluezone。 Reflection 有一个不错的 .NET API,但访问 Bluezone 的唯一方法是通过 COM。
我在解决方案中有一个通用的 class,它表示 Reflection 或 Bluezone 对象,它会抓住现有的客户端,无论它是什么,并与之通信。
在大多数情况下,一切正常。当我通过任何项目访问 Bluezone COM 对象时,它的功能就像反射一样。
问题似乎出在我在后台工作程序中访问 Bluezone 对象时。后台工作者似乎无法在主线程上看到 COM 对象。
在调试模式下评估 COM 对象时,所有属性都显示错误 "The function evaluation requires all threads to run"。
我知道这是不可能的,但是有谁知道管理它的方法以便我可以在后台线程中访问前台 COM 对象?
我曾与供应商就许多问题进行过合作,他们非常出色,但我觉得这可能是一件 .NET/COM 事情。
我最后的办法是删除所有后台工作人员并让用户处理屏幕冻结,但我真的不想那样做。我的另一个选择是在后台工作程序中实例化 COM 对象,但此操作会产生相关成本。我试过 Marshal.GetActiveObject("")
,但要么不起作用,要么我不知道应用程序的正确名称。
如果有人对 COM 和后台工作人员有过类似的经历,我将欢迎任何见解。
这在很大程度上是为 COM 组件设计的。与 .NET 类 非常不同,如果组件告诉 COM 它不支持线程,COM 会保持代码线程安全。由 ThreadingModel 注册表项配置。 COM 通过自动封送调用自动确保满足此要求,相当于 .NET Framework 中的 Invoke()。
因此,即使您从 BackgroundWorker 的 DoWork() 事件处理程序进行调用,这些调用也不会 运行 在工作线程上执行,它们会在创建对象的线程上执行。如有必要,COM 创建的 STA 线程。
调试器知道这一点,它可以 "see" 它们就好了,它可以判断出任何 watch 表达式都无法执行。因为它冻结了进程中的 所有 线程,调试器线程除外。所以没办法,留言提醒。
调试神器而已。也许更多,您的 BGW 可能效率不高或仍然导致 UI 线程挂起。检查 this post 创建 COM 友好线程的代码。