Мы должны использовать сторонний элемент управления ActiveX.
Единственная проблема заключается в том, что слой в нашем программном обеспечении является бизнес-слоем и не имеет доступа к окну или форме. Он также работает на отдельных потоках (и должен работать из любого потока), которые не являются STA.
Вместо того, чтобы нарушать наше разделение пользовательского интерфейса от бизнес-логики, мы использовали это обходное решение, чтобы заставить его работать:
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 из неизвестной многопоточной среды? Мы пытаемся написать наш класс таким образом, чтобы обернуть элемент управления, но он будет работать из любого потока.
UPDATE: в качестве ответа мы действительно предпочли бы использовать стандартный COM-объект и вообще не использовать элемент управления. Наша проблема заключалась в том, что мы получили бы ошибку "(Исключение из HRESULT: 0x8000FFFF (E_UNEXPECTED)" при первом методе или свойстве, которое мы вызываем для COM-объекта. Это довольно общая ошибка, которую мы не получаем при использовании ActiveX, любые идеи?
UPDATE: наш ocx является "CX25.ocx", используя tlbimp.exe, мы получаем CX25Lib.dll. Используя aximp.exe, мы получаем AxCX25Lib.dll и CX25Lib.dll. CX25Lib.dll не работает ни в одном случае. Работает AxCX25Lib.dll.