Безопасность потоков с использованием OCX из C # .NET - PullRequest
4 голосов
/ 11 февраля 2011

Я довольно долго не использовал OLE / COM в качестве разработчика, но в настоящее время мне нужно использовать некоторые сторонние библиотеки кода OCX из программы на C #.

Программа C # использует многопоточность (это сервер сокетов TCP). OCX помечены как модель резьбы квартиры. Из моего прочтения я пришел к выводу, что если я буду осторожен в создании одного экземпляра каждого OCX для потока и только для использования этого экземпляра из потока, который его создал, у меня все будет в порядке.

Я тоже сделал: -

myThread.SetApartmentState(ApartmentState.STA);

перед началом каждого потока.

Должно ли этого быть достаточно для безопасного использования OCX?

Симптом, который я вижу, состоит в том, что все потоки могут создавать OCX, но на случайной основе вызовы для подготовки и инициализации OCX не выполняются. Похоже, они не возвращают никакой полезной информации о том, почему.

Может кто-нибудь объяснить, что я вижу, или дать мне руководство по безопасному использованию этих OCX из многопоточного кода?

В качестве альтернативы, я должен просто отказаться и создать один экземпляр каждого и всех OCX в одном потоке и отправить все вызовы к ним через потокобезопасную очередь или подобное?

Ответы [ 3 ]

1 голос
/ 11 февраля 2011

Пометка компонента как резьбы в Apartment - это всего лишь утверждение разработчика компонента. Вокруг множество разработчиков компонентов, которые не понимают многопоточность, и даже те, кто понимает многопоточность, иногда ошибаются, поэтому доверять этому утверждению - акт веры.

Лично я очень осторожен в использовании сторонних компонентов в многопоточной среде по этой причине. За исключением тех, которые, как я знаю, имели очень широкое распространение в многопоточных приложениях и / или для которых я знаю, я могу получить адекватную поддержку.

Если у вас нет доступа к поддержке со стороны разработчика компонента или исходного кода для компонента, и вам абсолютно необходимо его использовать, то вариант создания отдельного экземпляра может быть хорошим прагматическим решением.

1 голос
/ 11 февраля 2011

Вы делаете что-то, чего пользователи управления, вероятно, никогда не делали раньше.Среды исполнения, такие как VB6, наиболее распространенное место использования .ocx, не позволяют создавать несколько потоков STA.Вполне вероятно, что код внутри элемента управления содержит глобальные переменные без какой-либо блокировки, необходимой для обеспечения безопасности.Результатом является случайный сбой.

Как ни крути, .NET имеет отличную поддержку TCP с пространством имен System.Net.Классы Socket, TcpClient и TcpServer.

0 голосов
/ 11 февраля 2011

Состояние квартиры должно управляться COM, поэтому установка состояния квартиры касается только вашего .Net кода состояния квартиры. Но квартира вашего COM-объекта должна быть доступна только из потока, который создал ваш COM-объект (тот, который вызывает CoInitialize). Что касается сбоя ваших вызовов COM-объекта, они могут исходить из базового кода. Какая у вас OCX lib?

...