使用 C# .NET 中的 OCX 实现线程安全

发布于 2024-10-17 04:17:42 字数 521 浏览 7 评论 0原文

作为一名开发人员,我已经有一段时间没有使用 OLE/COM 了,但我目前需要使用 C# 程序中的一些第 3 方 OCX 代码库。

C# 程序使用线程(它是一个 TCP 套接字服务器)。 OCX 被标记为单元线程模型。根据我的阅读,我得出的结论是,如果我小心地为每个线程创建每个 OCX 的一个实例,并且仅从创建它的线程中使用该实例,我应该没问题。

我也做了:-

myThread.SetApartmentState(ApartmentState.STA);

在开始每个线程之前。

这是否足以确保 OCX 的安全使用?

我看到的症状是线程都可以创建 OCX,但在明显随机的基础上,准备和初始化 OCX 的调用失败。他们似乎没有返回任何有用的信息来说明原因。

任何人都可以解释我所看到的内容,或者为我提供从线程代码安全使用这些 OCX 的指南吗?

或者,我是否应该放弃并在一个线程中创建每个和所有 OCX 的单个实例,并通过线程安全队列或类似队列向它们发送所有调用?

I haven't used OLE/COM for quite some time as a developer, but I currently have a need to use some 3rd party OCX code libraries from a C# program.

The C# program uses threading (it's a TCP socket server). The OCXs are marked as Apartment threading model. From my reading, I concluded that if I was careful to create one instance of each OCX per thread, and only to use that instance from the thread that created it, I should be OK.

I did also do:-

myThread.SetApartmentState(ApartmentState.STA);

before starting each thread.

Should this be enough to ensure safe use of the OCXs?

The symptom I'm seeing is that threads can all create OCXs but on an apparently random basis, the calls to prepare and initialize the OCXs fail. They don't seem to return any useful information as to why.

Can anyone explain what I'm seeing, or give me a guide to using these OCXs safely from threaded code?

Alternatively, should I just give up and create a single instance of each and all OCXs in one thread, and send all calls to them via a threadsafe queue or similar?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

獨角戲 2024-10-24 04:17:42

将组件标记为单元线程只是组件开发人员的一个断言。周围有很多组件开发人员不了解线程,甚至那些了解线程的人有时也会出错,因此相信这一断言是一种信仰行为。

就我个人而言,出于这个原因,我对在多线程环境中使用第三方组件非常谨慎。除了那些我知道在多线程应用程序中有非常广泛的接触的人,和/或我知道我可以获得足够的支持的人。

如果您无法获得组件开发人员的支持或组件的源代码,并且您绝对需要使用它,那么创建单个实例的选项可能是一个很好的实用解决方案。

Marking a component as Apartment threaded is just an assertion from the component developer. There are plenty of component developers around who don't understand threading, and even those who do understand threading sometimes get it wrong, so it's an act of faith to trust this assertion.

Personally I'm very wary of using 3rd party components in a multithreaded environment for that reason. Except those that I know have had very wide exposure in multithreaded applications, and/or for which I know I can get adequate support.

If you don't have access to support from the component developer, or source code for the component, and you absolutely need to use it, then the option of creating a single instance may be a good pragmatic solution.

嘿哥们儿 2024-10-24 04:17:42

您正在做一些控制用户以前可能从未做过的事情。 VB6(最常使用 .ocx 的地方)等运行时环境不允许创建多个 STA 线程。控件内的代码很可能包含全局变量,而无需任何确保安全所需的锁定。随机失败是结果。

抛开它吧,.NET 通过 System.Net 命名空间对 TCP 提供了出色的支持。 Socket、TcpClient 和 TcpServer 类。

You are doing something that the control users probably never did before. Runtime environments like VB6, the most common place where .ocx are used, do not allow creating multiple STA threads. It is pretty likely that the code inside the control contains global variables without any of the locking required to make that safe. Random failure is the outcome.

Ditch it, .NET has excellent support for TCP with the System.Net namespace. Socket, TcpClient and TcpServer classes.

如痴如狂 2024-10-24 04:17:42

公寓状态应由 COM 管理,因此设置公寓状态仅涉及您的 .Net 代码公寓状态。
但是 COM 对象的单元只能从创建 COM 对象的线程(调用 CoInitialize 的线程)访问。
至于您对 COM 对象的调用失败,它们可能来自底层代码。你的 OCX 库是什么?

The Apartment state should be managed by COM, so setting the apartment state only concerns your .Net code apartment state.
But the apartment of your COM object should only be accessible from the thread which created your COM object (the one calling the CoInitialize).
As for the failure of your calls to the COM object, they might come from underlying code. What is your OCX lib ?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文