Модераторы: MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Потоки и маршалинг в Apartment моделе 
:(
    Опции темы
Felan
Дата 29.5.2008, 14:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 284
Регистрация: 2.8.2007
Где: Самара

Репутация: нет
Всего: 7



Есть COM-объект в длл, т.е. inproc server. Потоковая модель Apartment. Вызывается из JavaScript, из IE. У объекта есть события. Назначаются в JavaScript.
В объекте создается еще один поток (это поточный класс НЕ COM, обычный класс, наследник от TObject, для работы с оборудованием). В этом классе, в возникают разные события. Эти события надо передать в JavaScript.

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

С одной стороны, проблема решается маршалингом. Сделал еще один интрефейс, который содержит методы вызова COM-событий. Этот интерфейс реализовал классом самого COM-объекта, т.к. COM-объект реализует два интерфейса, свой собственный и тот, через который я вызываю события.

Маршалинг сделал так:

  FEventFireForMarshal := TStreamAdapter.Create(TMemoryStream.Create(), soOwned);
  OleCheck( CoMarshalInterface(FEventFireForMarshal, IID_IBIllValidatorAXEventFire, Self as IUnknown, MSHCTX_INPROC, nil, MSHLFLAGS_TABLESTRONG ) );



Делаю его в методе инициализации, так, что бы потом можно было при возникновении события демаршалировать интерфейс для вызова событий любое количество раз.
В деструкторе вызываю CoReleaseMarshalData(FEventFireForMarshal);

Т.е. когда в классе работы с устройством возникает событие, в ком-объекте вызывается обработчик, такой:

      try
        OleCheck( CoInitialize(nil) );
        FEventFireForMarshal.Seek(0, STREAM_SEEK_SET, vInt64);
        WriteToLog('CoUnmarshalInterface');
        OleCheck( CoUnmarshalInterface(FEventFireForMarshal, IID_IBIllValidatorAXEventFire, vEvInt) );

        if vEvInt <> nil then
          vEvInt.FireOnEscrowEvent( TBillValidator.billTypeToCode( aBill ) );
      finally
        CoUninitialize();
      end;


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

Все это работает.

Если я делаю метод ком-объекта, который вызывается из ява-скрипта, и содержит цикл опроса поточного класса управления устройством (поля класса находятся за критическими секциями) и ждет определенного состояния оборудования (все это происходит в контексте потока ком-объекта), а в это время происходит какое либо событие в поточном классе, то, должно быть вызвано соответствующее событие COM. Событие должно отработать, а цикл мониторинга состояния оборудования, должен продалжится и завершится со временем.

Проблема в том, что когда во время этого цикла доходит до демаршалинкга, а точнее до вызова ф-ции CoUnmarshalInterface(...), виснет эксплорер.

В чем может быть проблема?

Сначала подумал, что нужно сделать цикл обработки сообщенией в поточном классе (т.к. он "подключается" к STA апартаментам), но это не помогло.
Нужен ли вообще во втором потоке этот цикл? Поток же не клиентский. И в данном случае не важно?


--------------------
// Любая сложная система - это темный лес. Каждый в этом лесу протаптывает свои тропинки, по ним и бегает. Лишь изредка, сходя с них, мы находим много интересного, а порою и страшного.
PM MAIL WWW ICQ   Вверх
Felan
Дата 30.5.2008, 10:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 284
Регистрация: 2.8.2007
Где: Самара

Репутация: нет
Всего: 7



Насколько мне сказали, IE использует STA модель. Когда ActiveX тоже использует эту модель, события назначенные в JavaScript работают, а когда другую, то нет.
Насколько я понимаю, это потому, что объект создается в другой команте (апартаментах...), но почему не работает вызов событий?


--------------------
// Любая сложная система - это темный лес. Каждый в этом лесу протаптывает свои тропинки, по ним и бегает. Лишь изредка, сходя с них, мы находим много интересного, а порою и страшного.
PM MAIL WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: ActiveX/СОМ/CORBA"

Rrader
Girder

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами


  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Delphi
  • Вопросы по SQL и вопросы по базам данных, не связанные с Delphi, задавать здесь

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Rrader, Girder.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: ActiveX/СОМ/CORBA | Следующая тема »


 




[ Время генерации скрипта: 0.0428 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.