![]() |
|
![]() ![]() ![]() |
|
Андреy |
|
|||
Новичок Профиль Группа: Участник Сообщений: 23 Регистрация: 9.4.2008 Репутация: нет Всего: нет |
Добрый день. Помогите пожалуйста прояснить ситуацию.
Задача следующая: клиент может создавать несколько потоков, в котором будут вызываться методы DLL COM сервера (в частном случае, один итот же метод). Почитав статьи про апартаменты и все дела, поначалу реализовал сервер с моделью потоков apartment, и решил, что все будет ОК. К тому же нижеприведенный код работает (как выяснилось, лишь иногда). Сервер написан на ATL+MFC Процедура, выполняющаяся в очередном потоке (клиент на Delphi, но не суть):
Рассуждения были следующие (неправильные): 1-ый запущенный поток загружает DLL сервера и создает экземпляр COM объекта, 2-ой запущенный поток создает новый экземпляр СОМ объекта. Сам COM объект содержит только инкапсулированные данные, глобальных переменных нет. Одно время наблюдал успешный параллельный вызов методов в разных потоках (читались данные с устройств по локальной сети, путаницы не было, данные поступали от каждого девайса свои). Но я не замечал следующих проблем: 1. Иногда 1 поток при попытке создания COM объекта выдает ошибку "Class already exists" (см. LogException(SysErrorMessage(GetLastError())). При этом это получается не ошибка, установленная внутри вызова метода (я не устанавливаю там такой код), это система выдает, уже после. 2. Еще момент — внутри кода метода сервера я отслеживаю ID потока, в котором выполняется метод. Имею следующее: клиент создает 2 потока, в обоих потоках выполняется метод, и он записывает в лог ID лишь одного процесса. 3. Метод при работе записывает в лог ход процесса — так вот иногда 1 поток записывал все, а 2-ой — не все (значит, он 1-ый перекрывал работу 2-го). Я поменял потоковую модель — сделал Both. Результат: в лог теперь пишется все, но вот ID процесса по-прежнему один и тот же. Но ведь по идее в каждом потоке создан отдельный экземпляр COM объекта. В общем, как делаются такие DLL COM сервера (приложение-клиент хочет одновременно в разных потоках запускать метод на выполнение)? |
|||
|
||||
jonie |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5613 Регистрация: 21.8.2005 Где: Владимир Репутация: 5 Всего: 118 |
апартаменты...
вот у меня есть очень хорошая дока по ним. мб она не поможет вам, но внесет ясность однозначно. Присоединённый файл ( Кол-во скачиваний: 16 ) ![]() -------------------- Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет... |
|||
|
||||
jonie |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5613 Регистрация: 21.8.2005 Где: Владимир Репутация: 5 Всего: 118 |
Итак, если у вас STA СЕРВЕР, то вы объявили неправильно клиента: нужно объявить его как MTA (CoInitializeEx(0, COINIT_MULTITHREADED) вывать) (если вы вызываете метод одного объекта клиента в разных потоках без маршалинга).
Если ваш сервер STA и, метод одного объекта вызывается из разных потоков без явного маршалинга (передачей туда указателя), то вызовы будут идти в разных потоках (по сути своей это прямой вызов из потока метода по указателю, без каки-либо прокси объектов). Нужно уведомлять систему COM о таких намерениях - делая маршалинг. ..... Это сообщение отредактировал(а) jonie - 25.3.2009, 00:23 -------------------- Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет... |
|||
|
||||
![]() ![]() ![]() |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: COM/DCOM/ActiveX/ATL/CORBA | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |