如何根据需要启动/停止监控Delphi线程?

Mar*_*ski 1 delphi multithreading ondemand

我一直在寻找一种方法来监控Delphi中特定的注册表更改.在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;
Run Code Online (Sandbox Code Playgroud)

在我的应用程序中,我将需要按需启动和停止此线程,但上面的代码不允许这样做.只设置Terminated标志是不行的.

以某种方式告诉线程停止等待,然后释放它并在需要时创建一个新的就足够了.如何更改此代码才能实现?

mgh*_*hie 8

使用WaitForMultipleObjects()两个事件的数组而不是WaitForSingleObject().一个手动重置事件添加到Thread类,并表示它已设置后TerminatedTrue.检查两个事件中哪个已发出信号的返回值,并采取相应措施.

编辑:

一些最小的Delphi 2009代码来演示这个想法.您必须添加SyncObjs到已用单位列表中,然后添加

  fTerminateEvent: TEvent;
Run Code Online (Sandbox Code Playgroud)

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;
Run Code Online (Sandbox Code Playgroud)

您只需要在问题中添加代码即可.只需尝试释放线程实例就可以完成解锁线程所需的一切(如有必要).