Есть одна практическая задача, но для ее реализации хотелось бы разобраться в подразделениях в COM хотя бы на уровне общих абстракций.
Прочитал статью на rsdm.ru (Понимание подразделений в COM) и сразу несколько вопросов:
1. Как я понял, что com-клиент, что com-сервер запускаются в подразделении. Это подразделение может быть — STA, MTA или NTA.
Вид подразделения для клиента выбирается в зависимости от параметров CoInitializeEx().
Вид подразделения для сервера выбирается в зависимости от записи в реестре.
Так ?
2. >> Вид подразделения для клиента выбирается в зависимости от параметров CoInitializeEx().
А как в случае VB ?
3. Вид подразделения для сервера выбирается в зависимости от записи в реестре.
Это задается тем, как реализован сервер. То есть, если я не меняя com-сервера просто поменяю значение в реестре, выделяемое подразделение не изменится ?
Пока вроде все, не хотелось бы задавать более конкретные вопросы без понимания этих принципов.
Здравствуйте, DemAS, Вы писали:
DAS> 1. Как я понял, что com-клиент, что com-сервер запускаются в подразделении. Это подразделение может быть — STA, MTA или NTA. DAS> Вид подразделения для клиента выбирается в зависимости от параметров CoInitializeEx(). DAS> Вид подразделения для сервера выбирается в зависимости от записи в реестре. DAS> Так ?
Угу. В exe-сервере иначе.
DAS> 2. >> Вид подразделения для клиента выбирается в зависимости от параметров CoInitializeEx(). DAS> А как в случае VB ?
Вроде, апартмент, т.е. STA.
DAS> 3. Вид подразделения для сервера выбирается в зависимости от записи в реестре. DAS> Это задается тем, как реализован сервер.
Не реализован, а зарегистрирован.
DAS>То есть, если я не меняя com-сервера просто поменяю значение в реестре, выделяемое подразделение не изменится ?
DAS>> 2. >> Вид подразделения для клиента выбирается в зависимости от параметров CoInitializeEx(). DAS>> А как в случае VB ?
SH>Вроде, апартмент, т.е. STA.
Подожди.
1) Есть апартмент. Он может быть либо STA, либо MTA, либо NTA.
Поэтому не понятно следствие: апартмент -> STA.
2) То есть, на VB нельзя создать клиента MTA ? Почему такая ущербность ?
DAS>> 3. Вид подразделения для сервера выбирается в зависимости от записи в реестре. DAS>> Это задается тем, как реализован сервер. SH>Не реализован, а зарегистрирован. DAS>>То есть, если я не меняя com-сервера просто поменяю значение в реестре, выделяемое подразделение не изменится ? SH>Изменится. И всё может окончится плохо.
Нет. Получается именно как реализован (в коде). То есть все зависит не только от регистрации (реестр).
Здравствуйте, DemAS, Вы писали:
DAS> Подожди. DAS> 1) Есть апартмент. Он может быть либо STA, либо MTA, либо NTA. DAS> Поэтому не понятно следствие: апартмент -> STA.
Я виниоват, использовал сокращение. Apartment-threaded — так называются компоненты, которые должны работать в этом режиме. Ну я и режим так же назвал.
DAS> 2) То есть, на VB нельзя создать клиента MTA ?
Я в VB почти никогда ничего не знаю. Но по слухам — да. В скриптах тоже самое.
DAS> Почему такая ущербность ?
Это к MS, не ко мне. Наверное, им так было проще. А производительности от VB никто никогда и не требовал.
DAS> Нет. Получается именно как реализован (в коде). То есть все зависит не только от регистрации (реестр).
Почему ты так решил? И какое именно место кода по твоему влияет на тип апартмента?
Здравствуйте, DemAS, Вы писали:
DAS> Нет. Получается именно как реализован (в коде). То есть все зависит не только от регистрации (реестр).
Именно, какая синхронизация реализована в коде, такой апартмент и запрашивается от клиента. Если клиент его не обеспечил, то он создается автоматически с маршаллингом в реальный апартмент клиента.
Здравствуйте, Vi2, Вы писали:
Vi2>Здравствуйте, DemAS, Вы писали:
DAS>> Нет. Получается именно как реализован (в коде). То есть все зависит не только от регистрации (реестр).
Vi2>Именно, какая синхронизация реализована в коде, такой апартмент и запрашивается от клиента. Если клиент его не обеспечил, то он создается автоматически с маршаллингом в реальный апартмент клиента.
Но если поменять регистрацию, а код оставить старый, то апартмент изменится и с неплохой вероятностью ничего работать не будет. Т.к. "запрашивается от клиента" == "прописывается в реестр" (для dll). Или я чего-то упустил? Если нет, то я это и имел ввиду.
DAS> 1. Как я понял, что com-клиент, что com-сервер запускаются в подразделении. Это подразделение может быть — STA, MTA или NTA.
Скажем по другому — они должны работать в подразделениях
DAS> Вид подразделения для сервера выбирается в зависимости от записи в реестре. DAS> Так ?
грубо говоря не сервера, а КоКласса, т.к. в сервере может быть несколько объектов
в реестре задаем потоковую модель — в которой мы хотим чтобы работал наш объект
DAS> Пока вроде все, не хотелось бы задавать более конкретные вопросы без понимания этих принципов.
Если найдешь у когото книгу Девида Чаппела "технология активХ и оле" отрывай с руками
Там все подробно расжевано. я ни в одной книге не встречал такого красивого и понятного описания
SH>Но если поменять регистрацию, а код оставить старый, то апартмент изменится и с неплохой вероятностью ничего работать не будет. Т.к. "запрашивается от клиента" == "прописывается в реестр" (для dll). Или я чего-то упустил? Если нет, то я это и имел ввиду.
Да, именно это я и имел в виду. То есть, если я имею чужой com-сервер, не имея его исходников 0 — то менять апартмент в реестре потенциально опасно, а следовательно делать не следует.
Так ?
Что же мне нужно сделать, чтобы изменить апартмент чужого com-сервера ? Как я понимаю, что-то изменить в его исходниках(которых у меня нет ). Поэтому я и говорю, что "настоятельно рекомендуемый" апартент сервера задается кодом сервера, а в реестре отображены лишь рекомендации(интерфейс) по работе с ним.
Всем большое спасибо за ответы. Теперь попробую плавно перейти к практической задаче.
Для начала еще один теоретический вопрос. Связаны либо как-нибудь подразделения с асинхронностью (возможностью неблокирующего вызова) в COM.
Читая статью про подразделения в com, сделал вывод, что свзяны. Например, по этой фразе:
STA-шные объекты никогда не обрабатывают более одного вызова в один момент времени.
А статья "Асинхронные вызовы COM-компонентов в Windows 2000", прихожу к выводу, что нет:
Начнем с обзора клиентов, производящих неблокирующие вызовы, затем перейдем к асинхронным серверам. В процессе чтения не забывайте, что серверы и клиенты практически независимы друг от друга в аспекте асинхронных операций. Другими словами, объект не делает ничего особенного, чтобы позволить клиенту произвести его неблокирующий вызов, а клиенту абсолютно ничего не нужно делать, чтобы позволить объекту обрабатывать вызовы его методов асинхронно. То, как клиент производит вызов, определяет, является вызов блокирующим или неблокирующим, а то, как объект откликается на входящие вызовы, определяет, обрабатываются эти вызовы синхронно или асинхронно.
Здравствуйте, DemAS, Вы писали:
DAS> Что же мне нужно сделать, чтобы изменить апартмент чужого com-сервера ? Как я понимаю, что-то изменить в его исходниках(которых у меня нет ). Поэтому я и говорю, что "настоятельно рекомендуемый" апартент сервера задается кодом сервера, а в реестре отображены лишь рекомендации(интерфейс) по работе с ним.
В реестре хранятся данные не для того, чтобы их можно было менять, а чтобы СОМ смог создать кокласс. Соотв-но нельзя менять настройки чужого сервака — это его и только данные. Короче нет там никаких рекомендаций — поменяеть апартмент чужого сервака — все равно что пропатчить его код.
Здравствуйте, DemAS, Вы писали:
DAS>Здравствуйте, DemAS, Вы писали:
DAS> Всем большое спасибо за ответы. Теперь попробую плавно перейти к практической задаче.
DAS> Для начала еще один теоретический вопрос. Связаны либо как-нибудь подразделения с асинхронностью (возможностью неблокирующего вызова) в COM.
НЕТ, ты путаешь синхронизацию и асинхронность.
DAS> Читая статью про подразделения в com, сделал вывод, что свзяны. Например, по этой фразе: DAS>
DAS> STA-шные объекты никогда не обрабатывают более одного вызова в один момент времени.
DAS>
Это значит что следующий вызов НЕ будет обработат пока не отработает ПЕРВЫЙ.
У STA свой цикл сообщений, из которого по очереди выгребаются сообщения.
Здравствуйте, LaFlour, Вы писали:
LF> НЕТ, ты путаешь синхронизацию и асинхронность.
Ок. Может быть здесь и есть мое непонимание
Если не сложно — можешь привести определения синхронизации и асинхронности ?
1. Если я два раза вызываю метод com сервера и наблюдаю, как они вызываются — поочереди или одновременно — это что ?
2. Если я из класса вызываю метод com — объекта и смотрю в какой момент управление вернется в вызвавшую программу — сразу или только после отработки com — метода — это что ?
Здравствуйте, DemAS, Вы писали: DAS>Если не сложно — можешь привести определения синхронизации и асинхронности ?
DAS>1. Если я два раза вызываю метод com сервера и наблюдаю, как они вызываются — поочереди или одновременно — это что ?
Синхронизация вызовов. В первом случае вызовы синхронизированы (сериализованы) системой. Твой объект "живет" в STA. Во втором случае вызовы не синхронизированы, твой объект "живет" в MTA, или ты его неправильно отмаршалил.
DAS>2. Если я из класса вызываю метод com — объекта и смотрю в какой момент управление вернется в вызвавшую программу — сразу или только после отработки com — метода — это что ?
Это вызов асинхронного метода. Это связано только с реализацией com-объекта, и никак не связано с апартментами (подразделениями) com.
Здравствуйте, rus blood, Вы писали:
DAS>>2. Если я из класса вызываю метод com — объекта и смотрю в какой момент управление вернется в вызвавшую программу — сразу или только после отработки com — метода — это что ? RB>Это вызов асинхронного метода. Это связано только с реализацией com-объекта, и никак не связано с апартментами (подразделениями) com.
Кажется начинаю понимать.
Теперь тогда практический вопрос. Есть dll — com-объект. Он чужой и исходных кодов его у меня нету.
Пишу клиента, дергаю в нем метод com-объекта и наблюдаю, то, что управдение возвращается клиенту только после окончания работы com-метода.
Можно ли это побороть без изменения Com-сервера ?
Здравствуйте, DemAS, Вы писали:
DAS>Здравствуйте, LaFlour, Вы писали:
LF>> НЕТ, ты путаешь синхронизацию и асинхронность.
DAS> Ок. Может быть здесь и есть мое непонимание
DAS> Если не сложно — можешь привести определения синхронизации и асинхронности ?
DAS> 1. Если я два раза вызываю метод com сервера и наблюдаю, как они вызываются — поочереди или одновременно — это что ?
Если твой объект работает в STA то методы будут вызываться по очереди. Твои вызовы будут синхронизированы внутренней очередью сообщений.
в многопоточности они могут одновременно вызываться.
Но в обоих случаях все сразу возвращается, по мере исполнения.
Синхронизация это доработка клиента/сервера чтобы они могли возвращать ответ по твоему желанию
Здравствуйте, LaFlour, Вы писали:
DAS>> 1. Если я два раза вызываю метод com сервера и наблюдаю, как они вызываются — поочереди или одновременно — это что ? LF> Если твой объект работает в STA то методы будут вызываться по очереди. Твои вызовы будут синхронизированы внутренней очередью сообщений.
ОК.
LF>в многопоточности они могут одновременно вызываться.
Имеется в виду, когда клиент создает несколько потоков и из каждого потока вызывает com метод ?
Или имеется в виду, что при каждом обращеннии к com-объекту он (com-объект) создает еще один поток для работы с новым клиентом ?
LF>Но в обоих случаях все сразу возвращается, по мере исполнения.
Извини, не понял. Что возвращается ? Управление ? По мере исполнения — это значит тогда, когда com метод закончил работу. Так ?
LF>Синхронизация это доработка клиента/сервера чтобы они могли возвращать ответ по твоему желанию
Тоже не понял Что значит "ответ по моему желанию" ?
Здравствуйте, DemAS, Вы писали:
DAS>Кажется начинаю понимать.
DAS>Теперь тогда практический вопрос. Есть dll — com-объект. Он чужой и исходных кодов его у меня нету. DAS>Пишу клиента, дергаю в нем метод com-объекта и наблюдаю, то, что управдение возвращается клиенту только после окончания работы com-метода. DAS>Можно ли это побороть без изменения Com-сервера ?
При вызове любого метода управление возвращается только после того, как метод заканчивает работу. Вся остальная асинхронность эмулируется (т.е. сервер поддерживает специальный метод для старта какой-нить продолжительной операции, и метод(ы) для ее останова или получения нотификации о завершении операции.
Если сервер это не поддерживает, можешь сделать свой "объект" для асинхронных вызовов (пул потоков, маршаллинг объектов, вызов методов в рабочих потоках, получение нотификации о завершении операции).
Здравствуйте, DemAS, Вы писали:
LF>>в многопоточности они могут одновременно вызываться.
DAS> Имеется в виду, когда клиент создает несколько потоков и из каждого потока вызывает com метод ? DAS>Или имеется в виду, что при каждом обращеннии к com-объекту он (com-объект) создает еще один поток для работы с новым клиентом ?
Имеется в виду, что клиент может запустить несколько потоков, и каждый поток может вызывать методы com-объекта, и все они могут это делать одновременно, причем методы com-объекта будут отрабатываться в каждом потоке независимо (одновременно) от вызовов остальных методов из других потоков.
LF>>Но в обоих случаях все сразу возвращается, по мере исполнения. DAS> Извини, не понял. Что возвращается ? Управление ? По мере исполнения — это значит тогда, когда com метод закончил работу. Так ?
Управление возвращается после вызова метода. А что сделал метод — выполнил операцию, или запустил отдельный поток для выполнения операции — зависит от реализации сервера.