Мастера DELPHI, Delphi programming community Рейтинг@Mail.ru Титульная страница Поиск, карта сайта Написать письмо 
| Новости |
Новости сайта
Поиск |
Поиск по лучшим сайтам о Delphi
FAQ |
Огромная база часто задаваемых вопросов и, конечно же, ответы к ним ;)
Статьи |
Подборка статей на самые разные темы. Все о DELPHI
Книги |
Новинки книжного рынка
Новости VCL
Обзор свежих компонент со всего мира, по-русски!
|
| Форумы
Здесь вы можете задать свой вопрос и наверняка получите ответ
| ЧАТ |
Место для общения :)
Орешник |
Коллекция курьезных вопросов из форумов
KOL и MCK |
KOL и MCK - Компактные программы на Delphi
Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / rsdn.org

 
Чтобы не потерять эту дискуссию, сделайте закладку « предыдущая ветвь | форум | следующая ветвь »

Вызов OnTerminate в потоках из COM


User192   (22.04.13 13:28

Создаю COM сервер в dll. В сервере создается поток на OnTerminate которого назначается некоторое событие. Данное событие не вызывается, т.к. вызов OnTerminate производится через Sychronize (в котором поток зависает на WaitFor). Подскажите как можно корректно вызывать Synchronize из потока в COM?

unit BackgrounWorker;

{$WARN SYMBOL_PLATFORM OFF}

interface

uses
 Windows, ComObj, Messages, ActiveX, AxCtrls, Classes, Dialogs, BackgrounWorkerDemo_TLB, StdVcl;

type
 TWorkerThread = class(TThread)
 protected
   procedure Execute; override;
 end;

 TBackrgoundWorker = class(TAutoObject, (*IConnectionPointContainer, *) IBackrgoundWorker)
 private
   { Private declarations }
 public
   Thread : TWorkerThread;
   destructor Destroy; override;
   procedure OnWorkTerminate(Sender : TObject);
 protected
   procedure Work; safecall;
 end;

implementation

uses ComServ;

destructor TBackrgoundWorker.Destroy;
begin
 inherited;
end;

procedure TBackrgoundWorker.OnWorkTerminate(Sender : TObject);
begin
 ShowMessage('Work Terminate');
end;

procedure TBackrgoundWorker.Work;
begin
 Thread := TWorkerThread.Create(True);
 Thread.FreeOnTerminate := True;
 Thread.OnTerminate := OnWorkTerminate;
 Thread.Start;
 { главный цикл сообщений потока }

end;

{ TWorkerThread }

procedure TWorkerThread.Execute;
var
 i: Integer;
begin
 for i := 0 to 10 do
   Sleep(100);
 //OnTerminate не вызывается, т.к. используется Synchronize
end;

initialization
 TAutoObjectFactory.Create(ComServer, TBackrgoundWorker, Class_BackrgoundWorker,
   ciMultiInstance, tmApartment);

end.


han_malign   (26.04.13 13:09[1]

- очевидно, не использовать Synchronze, т.к. контейнер, который владеет основным потоком, ничего не знает о твоем classes.CheckSynchronize() и тем более о его контексте связывания...

- а вызвать в контексте потока в конце Execute...

а наружу, в случае STA модели, событие надо отдавать через явный маршалинг в котором и будет сделана вся необходимая сериализация...
CoMarshalInterface/CoUnmarshalInterface
или хелпер:
CoMarshalInterThreadInterfaceInStream/CoGetInterfaceAndReleaseStream

то бишь где то так:
procedure TBackrgoundWorker.Work;
begin
   ...
   if( S_OK = CoMarshalInterThreadInterfaceInStream(IBackrgoundWorker, self as IBackrgoundWorker, @Thread.FMarshalStream) )then begin
      Thread.Start
   end else begin
      Thread.Free;
      raise EOleException.Create('Мне лень', E_FAIL, 'Work', '', -1);
   end;
end;

procedure TWorkerThread.Execute;
var intf: IBackrgoundWorker;
begin
   ...
   if( S_OK = CoGetInterfaceAndReleaseStream(FMarshalStream, IBackrgoundWorker, @intf) )then
      intf.DoOnWorkTerminate(...);
end;


han_malign   (26.04.13 13:35[2]

З.Ы. и в контексте TWorkerThread надо соответственно
CoInitialize(nil);
...
intf:= nil;{при неявной(магической) очистке навернется после CoUninitialize();}
CoUninitialize();


User192   (08.05.13 14:38[3]

Ок... Перешел на сообщения


версия для печати

Написать ответ

Ваше имя (регистрация  E-mail 







Разрешается использование тегов форматирования текста:
<b>жирный</b> <i>наклонный</i> <u>подчеркнутый</u>,
а для выделения текста программ, используйте <code> ... </code>
и не забывайте закрывать теги! </b></i></u></code> :)


Наверх

  Рейтинг@Mail.ru     Титульная страница Поиск, карта сайта Написать письмо