我们需要使用第三方的ActiveX控件。
唯一的问题是,我们软件中的业务层没有访问窗口或表单的权限。此外,它运行在不支持单线程单元(STA)的不同线程上(并应该从任何线程工作)。
为了不破坏UI与业务逻辑的分离,我们采用了以下方法来使其正常工作:
Thread thread = new Thread((ThreadStart)
delegate
{
_myActiveX = new MyActiveXType();
_myActiveX.CreateControl();
//more initialize work
Application.Run();
});
thread.SetApartmentState(ApartmentState.STA);
thread.IsBackground = true;
thread.Start();
每当需要引用该控件时,我们调用 _myActiveX.BeginInvoke()
或 Invoke()
。在销毁该类(退出应用程序)时,我们释放控件并中止线程。
我的问题是,这种做法有什么问题吗?是否有更好的方法来处理这个问题?是否有更好的内置方法可以在未知的多线程环境中使用 ActiveX 控件?我们正在尝试以包装控件的方式编写我们的类,但希望它能够在任何线程中工作。
更新:正如一个答案所建议的那样,我们实际上更愿意使用标准的 COM 对象而不是使用控件。我们遇到的问题是我们会在调用 COM 对象的第一个方法或属性时收到错误 "(Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED)"。这是一个相当通用的错误,在使用 ActiveX 时我们不会遇到这个问题,有什么想法吗?
更新:我们的 ocx 是 "CX25.ocx",使用 tlbimp.exe 我们得到 CX25Lib.dll。使用 aximp.exe,我们得到 AxCX25Lib.dll 和 CX25Lib.dll。CX25Lib.dll 在任何情况下都无法工作。AxCX25Lib.dll 可以工作。