Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.12.03;
Скачать: CL | DM;

Вниз

Win API   Найти похожие ветки 

 
Тонго   (2006-07-24 01:50) [0]

Добрый день. Помогите с такой ситуацией. Есть DLL-ка ActiveX, в которой два метода WaitEvent – проверяет есть ли Event с именем EvName, если есть то ожидает его, если нет, создает и также ожидает. Второй метод ResEvent- проверяет есть ли Event с именем EvName, если есть то сигналит и закрывает хендл Event-а.
Из другого приложения, в отдельном потоке создается объект DLL-ки и запускается метод WaitEvent. Также в отдельном потоке создается объект DLL-ки и запускается метод ResEvent.
Объясняю в чем проблема. Из программы создается несколько Event-ов с разными именами, и ожидается сигнального состояния конкретного Event-а, но после запуска ResEvent сигналят сразу все Event-ы которые ожидались, хотя должен сигналить один, чье имя было передано.
Подскажите что я не так сделал. Заранее благодарен за ответы.
Код процедур ниже.

Initialization // DLL-ки
 TAutoObjectFactory.Create(ComServer, TRunEvent, Class_RunEvent,
   ciSingleInstance, tmFree);

---------------------------- в DLL --------------------------------
procedure TRunEvent.ResEvent(const EvName: WideString);
var
 hEvent: Cardinal;
 LastError: Integer;
begin
 hEvent := OpenEvent(EVENT_ALL_ACCESS, True, PChar(EvName));

 if hEvent = 0 then
 begin
   LastError := GetLastError;
   MessageBox(0, Pchar("#" + IntToStr(LastError) + ". " +
     SysErrorMessage(LastError)), "AddIn.RunEvent", MB_ICONERROR);
   Exit;
 end;

 if not PulseEvent(hEvent) then
 begin
   LastError := GetLastError;
   MessageBox(0, Pchar("#" + IntToStr(LastError) + ". " + SysErrorMessage(LastError)), "AddIn.RunEvent", MB_ICONERROR);
 end;

 if not CloseHandle(hEvent) then
 begin
   LastError := GetLastError;
   MessageBox(0, Pchar("#" + IntToStr(LastError) + ". " + SysErrorMessage(LastError)), "AddIn.RunEvent", MB_ICONERROR);
 end;
end;

procedure TRunEvent.WaitEvent(const EvName: WideString; var OutStr: WideString);
var
 hEvent: Cardinal;
 LastError: Integer;
 SA: TSecurityAttributes;
 SD: TSecurityDescriptor;
begin
 InitializeSecurityDescriptor(@SD, SECURITY_DESCRIPTOR_REVISION);
 SA.nLength := SizeOf(SA);
 SA.lpSecurityDescriptor := @SD;
 SA.bInheritHandle := True;

 hEvent := OpenEvent(SYNCHRONIZE, True, PChar(EvName));
 if hEvent = 0 then
 begin
   LastError := GetLastError;
   if LastError <> 2 then  // 2 = нет такого Eventa
   begin
     MessageBox(0, Pchar("#" + IntToStr(LastError) + ". " +
       SysErrorMessage(LastError)), "AddIn.RunEvent", MB_ICONERROR);
     Exit;
   end;

   hEvent := CreateEvent(@SA, True, False, PChar(EvName));
   if hEvent = 0 then
   begin
     LastError := GetLastError;
     MessageBox(0, Pchar("#" + IntToStr(LastError) + ". " +
       SysErrorMessage(LastError)), "AddIn.RunEvent", MB_ICONERROR);
     Exit;
   end;
 end;

 if WaitForSingleObject(hEvent, INFINITE) = WAIT_OBJECT_0 then
  OutStr := "SetEvent "" + EvName + ""."
 else
 begin
   LastError := GetLastError;
   if LastError <> 0 then
     MessageBox(0, Pchar("#" + IntToStr(LastError) + ". " +
       SysErrorMessage(LastError)), "AddIn.RunEvent", MB_ICONERROR);
   OutStr := "Not SetEvent "" + EvName + "".";
 end;
end;

---------------------------- в приложении --------------------------------
// один поток
procedure REv.Execute;
var
 CC: Variant;
begin
 try
   CoInitializeEx(nil, COINIT_MULTITHREADED);
   CC := CreateOleObject("AddIn.RunEvent");
 except
   MessageBox(0, Pchar(SysErrorMessage(GetLastError)), "", MB_ICONERROR);
   CC := Unassigned;
   Exit;
 end;

 CC.WaitEvent(EventName, OutStr);
 Synchronize(UpdateMemo);
 CC := Unassigned;
 CoUninitialize;
end;

// второй поток
procedure RevRes.Execute;
var
 CC: Variant;
begin
 try
   CoInitializeEx(nil, COINIT_MULTITHREADED);
   CC := CreateOleObject("AddIn.RunEvent");
 except
   MessageBox(0, Pchar(SysErrorMessage(GetLastError)), "", MB_ICONERROR);
   CC := Unassigned;
   Exit;
 end;

 CC.ResEvent(EventName);
 CC := Unassigned;
 CoUninitialize
end;


 
KilkennyCat ©   (2006-07-24 03:30) [1]

я б для начала REV.EXecute и RevRes.Execute нормально бы переписал, вспомнив про finally.


 
Тонго   (2006-07-24 06:23) [2]

Переписал, но проблемму это не решет.

// один поток
procedure REv.Execute;
var
 CC: Variant;
begin
 try
   CoInitializeEx(nil, COINIT_MULTITHREADED);
   CC := CreateOleObject("AddIn.RunEvent");
   CC.WaitEvent(EventName, OutStr);
   Synchronize(UpdateMemo);  
 finally
   //MessageBox(0, Pchar(SysErrorMessage(GetLastError)), "", MB_ICONERROR);
   CC := Unassigned;
   CoUninitialize;
 end;
end;

// второй поток
procedure RevRes.Execute;
var
 CC: Variant;
begin
 try
   CoInitializeEx(nil, COINIT_MULTITHREADED);
   CC := CreateOleObject("AddIn.RunEvent");
   CC.ResEvent(EventName);
 finally
   //MessageBox(0, Pchar(SysErrorMessage(GetLastError)), "", MB_ICONERROR);
   CC := Unassigned;
   CoUninitialize;
 end;
end;


 
Сергей М. ©   (2006-07-24 09:54) [3]


> сигналят сразу все Event-ы


Приведи дословно фрагмент лога, подтверждающего это ..



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

Текущий архив: 2006.12.03;
Скачать: CL | DM;

Наверх




Память: 0.48 MB
Время: 0.07 c
2-1163473730
Wood
2006-11-14 06:08
2006.12.03
Continue, вложенный цикл.


2-1163669091
Tor
2006-11-16 12:24
2006.12.03
Перевод значения Variant в Extended если значение равно Null


2-1163577126
DragonIG
2006-11-15 10:52
2006.12.03
Как можно из-под программы переписать строковые ресурсы в DLL


2-1163700111
Ingwar
2006-11-16 21:01
2006.12.03
Как прервать цикл ожидания посылки (ComPort 3.1 от WinSoft a)


4-1153743219
Сан Саныч
2006-07-24 16:13
2006.12.03
Как получить ID харда? Не серийник, а ID!