我一直在寻找一种方式来监控在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;

在我的应用程序将需要启动和停止按需这个线程,但上面的代码就不允许。只需设置终止标志不会做。

这将是足以以某种方式告诉线程停止等待,然后再释放它并在需要时创建一个新的。我怎样才能改变这种代码来实现这一目标?

有帮助吗?

解决方案

使用WaitForMultipleObjects()具有两个事件,而不是WaitForSingleObject()的阵列。一个手动重置事件添加到Thread类,并表示它已设置TerminatedTrue后。检查所述两个事件的已用信号通知的返回值,并采取相应的行动。

修改

一些最小的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;

您只需要在你的问题,将其添加的代码。只是试图释放线程实例将采取一切必要行动,以解除阻塞线程(如有必要)。

其他提示

而不是无限你应该有WaitForSingleObject的时间了一段时间后。循环继续,并终止这种方式被检查。

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理论上可以用于临时停车线,但截至2010年德尔福现在承认他们不安心使用。请参见 TThread.resume已被弃用德尔福在2010年我应该在的地方吗?使用和的 http://msdn.microsoft.com/en-us/library/ms686345%28VS.85%29.aspx

这工作,只是做小的变化如下而现在,当你调用终止:

  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