Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2003.09.11;
Скачать: [xml.tar.bz2];

Вниз

Внешний COM сервер и потоковая модель   Найти похожие ветки 

 
Юрий Федоров   (2003-08-27 18:53) [0]

Прошу прощения за возможно ламерский вопрос...
Это правда, что при создании внешнего сервера (exe) все запросы (вызовы методов КоКлассов) клиентов будут выполняться последовательно через PostMessage, игнорируя флаг ThreadingModel, переданный в конструктор TAutoObjectFactory?


 
Serginio666   (2003-08-27 19:04) [1]

А откуда такая информация????


 
Юрий Федоров   (2003-08-27 19:08) [2]

сказали, подтверждения или опровержения в документации не нашел, провел тест - похоже что так и есть...


 
Юрий Федоров   (2003-08-27 19:20) [3]

Поясню
На сервере есть метод, который длится 10 секунд.
Запускаю двух клментов - они создали 2 Ком-Объекта в рамках одного Ком-сервера. Вызываю из первого клиента этот метод, потом сразу из второго. Первый клиент получает управление через 10 секунд, второй - через 20


 
Serginio666   (2003-08-27 20:12) [4]

Какая версия Delphi, какая ThreadingModel???? не Single случайно???


 
Юрий Федоров   (2003-08-27 20:33) [5]

ThreadingModel free
D6


 
Serginio666   (2003-08-27 20:39) [6]

Для лучшей проверки выводи синхронизированные сообщения из разных потоках и попробуй Апартамент.


 
Юрий Федоров   (2003-08-27 21:31) [7]

Я все варианты пробовал :-)


 
Dred2k   (2003-08-27 21:55) [8]

> Юрий Федоров © (27.08.03 21:31) [7]

В серверах, созданных на D4 - именно такая ситуация. Выявлено с помощью GetCurrentThreadID. Наблюдается во всех вариантах потоковой модели. :( Кстати, такая модель в определенной степени удобна для реализации серверов с "простыми" дейтсвиями. Тем более, что пускать нитки внутри никто не запрещает (но это сложнее, чем мультитреадная модель сама по себе).
А вот на D6 такого уже нет, к радости. В ней я создал сервер с полноценной мультитреадной моделью (главная нить + нить на каждый коннект).


 
Юрий Федоров   (2003-08-28 11:40) [9]

Где могут быть подводные камни ?
Ситуация теперь такая - при выборе tmFree все вроде работает как надо - потоки разные. При выборе tmApartment оба запроса (к разным экземплярам coClass"а)выполняются в одном и том же потоке (последовательно) - проверил по GetCurrentThreadID.
Мне для моей задачи наиболее подходит как раз tmApartment.
Может ли это зависеть от особенностей написания клиента? Или от каких-либо параметров библиотеки типов? Или от патчей на Delphi ?
UP


 
Юрий Федоров   (2003-08-28 12:55) [10]

Up
...
Такое впечатление что это какой-то баг...


 
Юрий Федоров   (2003-08-28 14:31) [11]

Ну, еще раз Ап, а потом пойду рыдать и плакать :-) :-(


 
Serginio666   (2003-08-28 15:11) [12]

Попробуй перед Application.Initialize явно задать апартамент

CoInitFlags:= COINIT_MULTITHREADED;
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;

Посмотри
http://www.rtfm.4hack.com/show.php?rs=1&sb=2&st=22


 
Serginio666   (2003-08-28 15:16) [13]

Небольшая выдержка

Отдельного обсуждения заслуживает инициализация потоковой модели COM для сервера, расположенного в DLL. Дело в том, что DLL может быть загружена любым потоком, который уже ранее создал свою «комнату». Поэтому сервер в DLL не может сам инициализировать требуемую ему потоковую модель. Вместо этого сервер при регистрации прописывает в реестре параметр ThreadingModel, который и указывает, в какой потоковой модели способен работать данный сервер. При создании сервера COM анализирует значение этого параметра и потоковой модели «комнаты» запросившего создание сервера потока и при необходимости создает для сервера «комнату» с требуемой потоковой моделью.

Параметр ThreadingModel может принимать следующие значения:

Apartment — сервер может работать только в STA. Если он создается из STA, то он будет создан в «комнате» вызывающего потока, если из MTA — COM автоматически создаст для него «комнату» c STA и proxy в «комнате» клиента;

Free — сервер может работать только в MTA. Если он создается из MTA, то он будет создан в «комнате» вызывающего потока, если из STA — COM автоматически создаст для него «комнату» c MTA и proxy в «комнате» клиента;

Both — сервер может работать как в STA, так и MTA. Объект всегда создается в вызывающей «комнате».

Если этот параметр не задан, сервер имеет потоковую модель Single. В этом случае он создается в Primary STA (то есть в STA потока, который первым вызвал CoInitialize), даже если создание сервера запрошено из потока, имеющего свою отдельную STA.


 
Dred2k   (2003-08-28 15:21) [14]

Замечательная ссылка:
http://www.geocities.com/SiliconValley/Campus/3207/Translations/
А вот, вроде, сайт автора:
www.intac.com/~bly/com/index.htm

О себя добавлю, что дельфя тут вполне может повести себе как тот Пятачок, от которого всего можно ожидать...
Особенности клиента на сервер не влияют, хотя теоретически модель выбирается сначала по серваку, затем по клиенту (если он так не может). Надежнее проверить во всех вариантах.


 
Юрий Федоров   (2003-08-28 15:28) [15]

>>Попробуй перед Application.Initialize явно задать апартамент

Пробовал, при этом мы фактически имеем tmFree, а мне нужен
tmApartment, то есть чтобы каждый ком-объект работал в своем потоке, но только в одном

Спасибо за ссылки, уже начал читать :-)


 
Serginio666   (2003-08-28 15:31) [16]

Для большего понятия
COINIT_APARTMENTTHREADED — для потока создается STA. Каждый поток может иметь (или не иметь) свою STA;

COINIT_MULTITHREADED — если в текущем процессе еще не создана MTA, создается новая MTA; если она уже создана другим потоком, поток «подключается» к ранее созданной. Иными словами, каждый процесс может иметь только одну MTA.


 
Юрий Федоров   (2003-08-28 15:57) [17]

Serginio666 (28.08.03 15:31) [16]
COINIT_APARTMENTTHREADED — для потока создается STA. Каждый поток может иметь ( или не иметь) свою STA;

На эту фразу я натолкнулся уже в добром десятке мест (видимо передрано из одного источника) :-)
Это непонятно - от чего зависит имеет поток свою СТА или нет ?


 
Serginio666   (2003-08-28 16:17) [18]

Попробуй для проверки задать для каждого объекта любой неодинаковое значение и при каждом вызове сравнивай с назначенным при tmApartment.
Насколько я понял при использовании MTA вызовы методов идут через RCP но при tmApartment вызовы методов происходят для созданного клиентом объекта, при tmFree через пул потоков с использованием одного объекта (Singleton).
В Net ессть достаточно простые понятия SingleCall,Singleton и активированные клиентом объекты.
Возможно опять я жестоко ошибаюсь.


 
Serginio666   (2003-08-28 16:22) [19]

Вернее при использовании MTA вызовы методов идут через RCP с использованием пул потоков но при tmApartment вызываются методы для определенного объекта,а для и tmFree либо случайного или единственного.


 
Serginio666   (2003-08-28 16:35) [20]

Исследуем
constructor TComObjectFactory.Create(ComServer: TComServerObject;
ComClass: TComClass; const ClassID: TGUID; const ClassName,
Description: string; Instancing: TClassInstancing;
ThreadingModel: TThreadingModel);
begin
IsMultiThread := IsMultiThread or (ThreadingModel <> tmSingle);
if ThreadingModel in [tmFree, tmBoth] then
CoInitFlags := COINIT_MULTITHREADED else
if (ThreadingModel = tmApartment) and (CoInitFlags <> COINIT_MULTITHREADED) then
CoInitFlags := COINIT_APARTMENTTHREADED;

//--------------------------------------------------


 
Юрий Федоров   (2003-08-28 16:46) [21]

>>Serginio666 (28.08.03 16:35) [20]
Я исследовал этот код :-)
Либо я уже начал тупить совсем, но я вижу, что
CoInitializeEx вызывается с флагом COINIT_APARTMENTTHREADED, это действительно так. И переменная IsMultiThread равна true... А поток один, хоть ты тресни :-)
Чувствую, забрезжил впереди COINIT_MULTITHREADED... А не хочется, ведь уже очень много написано без закладки на необходимость синхронизации в рамках одного объекта...


 
Serginio666   (2003-08-28 17:19) [22]

Если я прав в Serginio666 (28.08.03 16:22) [19]
то в рамках объекта ничего синхронизировать не надо, так как доступ к нему имеет только создавший его клиент. Еще раз повторюсь проверь на уникальные значения для каждого объекта.


 
Юрий Федоров   (2003-08-28 17:47) [23]

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


 
Serginio666   (2003-08-28 18:07) [24]

При Free нет смысла создавать несколько объектов. А запуск метода объекта в потоке может запускаться различными способам, в том числе и через ассинхронные процедуры APC с использованием пула потоков. А если доступ при MTA и tmApartment происходит только к созданному клиентом объекту то какой смысл синхронизировать в рамках объекта .


 
Юрий Федоров   (2003-08-28 18:55) [25]

Как это при Free нет смысла создавать несколько объектов, мне нужно несколько экземпляров с разными данными...

Нашел по одной из ссылок библиотеку с альтернативной реализацией ClassFactory - там все работает нормально, получатеся что Борланд напортачил... Похоже на то :-(


 
Юрий Федоров   (2003-08-28 19:07) [26]

Если кому интересно, чем все закончилось...

При использовании RemoteDataModule и соответственно
TComponentFactory все работает нормально и у Borland,
у меня же в первоначальном варианте была реализация через
потомка TAutoObject и соответственно TAutoObjectFactory.
Вопрос остался открытым потому что мне этот RemoteDataModule ни каким боком не уперся


 
Fantasist   (2003-08-29 01:46) [27]

Еще раз, что есть и что нужно? Я так понял, у тебя внепроцессорный объект (local-server), что с ним надо сделать?


> Это непонятно - от чего зависит имеет поток свою СТА или
> нет ?


Что тут непонятного. Если поток вызвал CoInitialize(Ex) без параметра COINIT_MULTITHREADED, то для него будет созданно STA. Если же он не вызывал CoInitialize, то для него вообще не будет назначенно никакого подразделения.


> Какая версия Delphi, какая ThreadingModel???? не Single
> случайно???


Я так понял, что обсуждается local-server? ThreadingModel для локальных серверов не существует. Да и нет такой модели "Single".


> Вернее при использовании MTA вызовы методов идут через RCP
> с использованием пул потоков но при tmApartment вызываются
> методы для определенного объекта,а для и tmFree либо случайного
> или единственного.


Извините, но вы кажется мешаете асфальт с салатом, либо я Вас не понял. RPC - это всего лишь сервис, который обеспечивает вызов процедур. Он используется OLE маршалерами и не более того. MTA или STA не имеют к этому никакого отношения. Интерфейсы внепроцессорного объекта всегда будут маршалиться в независимости от назначенного подразделения. Внутрепроцессорные объекты будут маршалиться, если вызывающая сторона находиться в другом подразделении. И везде, где есть маршалинг будет присутсвовать RPC(а точнее, их облегченная версия. LPC что ли.)


 
Serginio666   (2003-08-29 13:46) [28]

Несколько вопросов

Apartment — если из MTA — COM автоматически создаст для него «комнату» c STA и proxy в «комнате» клиента;

Тогда при CoInitFlags:= COINIT_MULTITHREADED; СОМ должен все создать автоматически.

Тогда зачем в TComponentFactory при tmApartment создается поток в котором создается объект и передается маршализированная ссылка ?????

Или посмотреть в сторону Синглетона ???

Не слишком ли дорого для каждого объекта создавать свой поток и синхронизировать вызовы через очередь сообщений потока ?????

Если ссылкой на объект владеет только клиент в одном своем потоке, нужна ли синхронизация при tmFree????

С другой стороны при tmFree может легче создать для каждого объекта критическую секцию и блокировать при каждом вызове метода интерфейса ????


 
Юрий Федоров   (2003-08-29 14:08) [29]

Всем спасибо, проблема решена путем наследования от TAutoObjectFactory по аналогии с TComponentFactory



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2003.09.11;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.53 MB
Время: 0.008 c
14-33753
Пробегал
2003-08-21 22:22
2003.09.11
Зачем вы баните прокси?


1-33569
astro
2003-08-28 19:35
2003.09.11
Где найти или как создать компонент? Подробности дальше...


3-33477
eds
2003-08-20 14:51
2003.09.11
Не создается файл *.gbk


14-33802
Nik8.
2003-08-22 11:25
2003.09.11
Help !


1-33590
dez
2003-08-28 12:42
2003.09.11
TdxEdit и др.





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский