요구에 따라 델파이 스레드 모니터링을 시작/중지하는 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/1734644

  •  20-09-2019
  •  | 
  •  

문제

델파이의 특정 레지스트리 변경 사항을 모니터링 할 수있는 방법을 찾고 있습니다. 찾았습니다 해결책 at About.com :

procedure TRegMonitorThread.Execute;
begin
  InitThread; // method omitted here
  while not Terminated do
  begin
    if WaitForSingleObject(FEvent, INFINITE) = WAIT_OBJECT_0 then
    begin
      fChangeData.RootKey := RootKey;
      fChangeData.Key := Key;
      SendMessage(Wnd, WM_REGCHANGE, RootKey, LongInt(PChar(Key)));
      ResetEvent(FEvent);

      RegNotifyChangeKeyValue(FReg.CurrentKey, 1, Filter, FEvent, 1);
    end;
  end;
end;

내 응용 프로그램에서는이 스레드가 주문형을 시작하고 중지해야하지만 위의 코드는이를 허용하지 않습니다. 종료 된 플래그를 설정하는 것만으로는 그렇지 않습니다.

어떻게 든 스레드에 대기를 중지 한 다음 해방하고 필요할 때 새로운 것을 만들도록 말하는 것이 충분할 것입니다. 이 코드를 어떻게 변경하여이를 달성하려면 어떻게해야합니까?

도움이 되었습니까?

해결책

사용 WaitForMultipleObjects() 대신 두 이벤트 배열이 있습니다 WaitForSingleObject(). 스레드 클래스에 수동 재설정 이벤트를 추가하고 설정 한 후에 신호를 보내십시오. Terminated 에게 True. 두 이벤트 중 신호를받은 반환 값을 확인하고 그에 따라 행동하십시오.

편집하다:

아이디어를 보여주기위한 최소 Delphi 2009 코드. 추가해야합니다 SyncObjs 중고 장치 목록에 추가하십시오

  fTerminateEvent: TEvent;

~로 private 스레드 클래스의 섹션.

constructor TTestThread.Create;
begin
  inherited Create(TRUE);
  fTerminateEvent := TEvent.Create(nil, True, False, '');
  // ...
  Resume;
end;

destructor TTestThread.Destroy;
begin
  fTerminateEvent.SetEvent;
  Terminate; // not necessary if you don't check Terminated in your code
  WaitFor;
  fTerminateEvent.Free;
  inherited;
end;

procedure TTestThread.Execute;
var
  Handles: array[0..1] of THandle;
begin
  Handles[0] := ...; // your event handle goes here
  Handles[1] := fTerminateEvent.Handle;
  while not Terminated do begin
    if WaitForMultipleObjects(2, @Handles[0], False, INFINITE) <> WAIT_OBJECT_0 then
      break;
    // ...
  end;
end;

질문에 코드를 추가하면됩니다. 스레드 인스턴스를 해제하려고 시도하면 스레드를 차단 해제하는 데 필요한 모든 것이 수행됩니다 (필요한 경우).

다른 팁

대신 Infinite에서는 기간이 지나면 WaitforsingleObject Time Out이 있어야합니다. 그렇게하면 루프가 계속되고 종료됩니다.

procedure TRegMonitorThread.Execute;
begin
  InitThread; // method omitted here
  while not Terminated do
  begin
    if WaitForSingleObject(FEvent, 1000) = WAIT_OBJECT_0 then
    begin
      fChangeData.RootKey := RootKey;
      fChangeData.Key := Key;
      SendMessage(Wnd, WM_REGCHANGE, RootKey, LongInt(PChar(Key)));
      ResetEvent(FEvent);

      RegNotifyChangeKeyValue(FReg.CurrentKey, 1, Filter, FEvent, 1);
    end;
  end;
end;

방법 tthread.suspend 및 tthread.resume 방법은 이론적으로 일시적인 스톱 스레드를 사용하는 데 사용될 수 있지만 Delphi 2010은 이제 사용하기에 안전하지 않다는 것을 인정합니다. 보다 tthread.resume은 Delphi-2010에서 더 이상 사용되지 않습니다. 그리고 http://msdn.microsoft.com/en-us/library/ms686345%28vs.85%29.aspx

이것은 작동합니다. 아래에서와 같이 작은 변경 만하며 이제 Ternatine에 전화 할 때 다음과 같습니다.

  TRegMonitorThread = class(TThread)
  ...
  public
    procedure Terminate; reintroduce;
...

procedure TRegMonitorThread. Terminate;  // add new public procedure
begin
  inherited Terminate;
  Windows.SetEvent(FEvent);
end;

procedure TRegMonitorThread.Execute;
begin
  InitThread;

  while not Terminated do
  begin
    if WaitForSingleObject(FEvent, INFINITE) = WAIT_OBJECT_0 then
    begin
      if Terminated then // <- add this 2 lines
        Exit;
      ...
    end;
  end;
end;
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top