Возможно ли иметь два экземпляра COM STA одного и того же компонента? - PullRequest
1 голос
/ 10 ноября 2008

У меня была проблема , обнаруженная в другом потоке здесь , мне нужно получить доступ к компоненту COM, который является STA. Я буду запускать его на двухъядерном компьютере, процесс с использованием этого компонента достигает только 50% процессорного времени. К сожалению, владельцы сказали, что они не могут изменить компонент на MTA, потому что компонент представляет собой гибридную систему, скомпилированную в Matlab, ядро ​​которой - C.

Поэтому я попытался загрузить два экземпляра класса COM в один и тот же процесс, причем разные потоки обращались к нему, но я не смог, только последний экземпляр COM стал пригодным для использования. Знаете ли вы что-нибудь, что может решить эту проблему?

Я планирую запустить два процесса моей службы на одном компьютере, чтобы достичь 100% процессорного времени. Это не очень хорошее решение, в основном потому, что эти серверы будут установлены за пределами нашей инфраструктуры.

Ответы [ 3 ]

2 голосов
/ 10 ноября 2008

По теме нескольких компонентов STA

Можно иметь два экземпляра одного и того же COM-компонента STA и обращаться к ним из C #. Единственное, что может помешать вам в таком сценарии, - это сам объект, если он реализован как одноэлементный объект.

Однако, если оба экземпляра находятся в одном потоке STA, активный вызов в одном из экземпляров заблокирует любые другие вызовы в этом потоке. Таким образом, если вы хотите, чтобы эти два экземпляра работали параллельно, вам нужно, чтобы они были в отдельных потоках STA. Чтобы быть в безопасности, я бы создал оба экземпляра в фоновых потоках. Это должно предотвратить блокировку вашего пользовательского интерфейса.

По теме STA против MTA для внешнего компонента

Я не уверен, почему находящийся в C компонент помешал бы ему быть MTA-объектом. Быть MTA означает, что объект должен внутренне синхронизировать свой доступ к состоянию и код управления между несколькими потоками.

ПРЕДУПРЕЖДЕНИЕ: Гадкий хак! :-) Если вы хотите немного поэкспериментировать, вы можете зайти в реестр и изменить модель потоков внешних компонентов с Apartment на Free, просто чтобы убедиться, что ваш код будет правильно работать с MTA. Однако их компонент, вероятно, сломается, поскольку они, вероятно, не написали поточно-ориентированный код, полагаясь на COM для их защиты.

Сделайте заметку на видном месте, чтобы позже отменить это изменение, чтобы у вас не было системы, в которой их код не работал и потратил бесчисленные часы, гоняясь за призраками. : -)

0 голосов
/ 11 ноября 2008

Фрэнси Пернов,

Я пытался работать с двумя потоками и инициализировать экземпляры в контексте каждого потока, но ошибка та же: (Исключение из HRESULT: 0x80004005 (E_FAIL)) *

Я сохраняю и извлекаю экземпляр через CallContext GetData и SetData.

0 голосов
/ 10 ноября 2008

Попробуйте зарегистрировать второй класс, используя ту же DLL. Учтите, что для полной безопасности вам может потребоваться отдельная копия библиотеки DLL с другим именем.

Просто помните, что класс STA COM (и, возможно, его DLL) не считается поточно-ориентированным для многопоточности, и вы ничего не можете сделать с этим внешним по отношению к классу COM.

...