Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: ActiveX/СОМ/CORBA > Com Automation Object


Автор: Fedia 25.9.2006, 08:29
Приветствую всех !

Столкнулся вот с какой задачей:
Реализован внешний Com-сервер автоматизации (Automation Object), обеспечивающий обратную связь со своими клиентами посредством событий:
Код

TDateListVes = class(TAutoObject, IConnectionPointContainer, IDateListVes)

//...

function TDateListVes.GetconnectionEnamerator: IEnumConnections;
var
  Container: IConnectionPointContainer;
  CP: IConnectionPoint;
begin
  Result:=nil;
  OleCheck(QueryInterface(IConnectionPointContainer, Container));
  OleCheck(Container.FindConnectionPoint(AutoFactory.EventIID, CP));
  CP.EnumConnections(Result);
end;

procedure TDateListVes.DoChange;
var
  EC: IEnumConnections;
  ConnectData: TConnectData;
  Fetched: Cardinal;
begin
  EC:=GetconnectionEnamerator;
  if EC <> nil then
  begin
    while EC.Next(1, ConnectData, @Fetched) = S_OK do
    if ConnectData.pUnk <> nil then
    if Assigned(ConnectData.pUnk) then
    try
      (ConnectData.pUnk as IDateListVesEvents).OnChange; //здесь получаем AV
    except
    end;  
  end;
end;

В процедуре DoChange получаем перечень клиентов сервера, затем перебираем клиентов и генерируем на их "стоках" событие OnChange. При закрытии программы - клиента на OnClose главной формы осуществляется отключение от сервера автоматизации:
Код

    ListCX: IDateListVes;
    //...
    InterfaceDisconnect(ListCX, IDateListVesEvents, FCookie);
    FEventSink.Free;
    ListCX:=nil;

Проблема в том, что приложение - клиент может быть закрыто через диспетчер задач (вкладка "Процессы") или какой-либо другой тяжелой артиллерией и процедура отключения от сервера не сработает -> сервер не будет знать о том, что клиент отключился и при попытка генерации события на "стоке" клиента он получит ошибку AV. Я поставил заглушку в виде блока try..except, но это ведь не дело. Подскажите как перед генерацией события мне проверить доступность клиента ?

ЗЫ: описал задачу как смог, если понадобятся уточнения, то спрашивайте.

Автор: drkot 25.9.2006, 12:35
Использование исключений это правильный путь, они для этой цели и созданы.
Нужно только добавить обработчик исключения который удалит клиента из списка, чтобы не возникало ошибок вдальнейшем.

Автор: Fedia 26.9.2006, 00:05
Цитата(drkot @  25.9.2006,  12:35 Найти цитируемый пост)
Нужно только добавить обработчик исключения который удалит клиента из списка, чтобы не возникало ошибок в дальнейшем.

По хорошему, если все же использовать try...except, то нужно конечно удалить клиента из перечня подключений, но реализовать это у меня не получается. Пробовал так:
Код

    try
      (ConnectData.pUnk as IDateListVesEvents).OnChange;
    except
      InterfaceDisconnect(ConnectData.pUnk, IDateListVesEvents, ConnectData.dwCookie);
      ConnectData.pUnk:=nil;
    end;

Да и все равно не хочется мне ловить в программе ошибки (тем более AV), т.к. это может быть чревато различными проблемами в дальнейшем. Поэтому вопрос о проверке доступности клиента остается открытым. B еще добавился вопрос: как в обработчике except…end уведомить сервер, что клиент  ConnectData.pUnk  отключился.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)