如何根据需要启动/停止监控Delphi线程? [英] How to start/stop a monitoring Delphi thread on demand?

查看:202
本文介绍了如何根据需要启动/停止监控Delphi线程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在寻找一种方法来监视Delphi中的特定注册表更改。在about.com上找到解决方案

I've been looking for a way to monitor for specific registry changes in Delphi. Found a solution 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;

在我的应用程序中,我需要根据需要启动和停止此线程,但上述代码不准许只要设置终止标志就不会这样做。

In my application I will need to start and stop this thread on demand, but the above code does not permit that. Just setting the Terminated flag won't do.

只要不知何故告诉线程停止等待,然后释放它,并在需要时创建一个新的。如何更改此代码以实现?

It would be sufficient to somehow tell the thread to stop waiting, then free it and create a new one when needed. How can I change this code to achieve that?

推荐答案

使用 WaitForMultipleObjects()具有两个事件的数组,而不是 WaitForSingleObject()。将一个手动重置事件添加到线程类,并在将终止设置为 True 后发出信号。检查返回值哪两个事件已经发出信号,并相应地执行。

Use WaitForMultipleObjects() with an array of two events instead of WaitForSingleObject(). Add a manual reset event to the thread class, and signal it after you have set Terminated to True. Check the return value which of the two events has been signalled, and act accordingly.

编辑:

一些极少的Delphi 2009代码来演示这个想法。您必须将 SyncObjs 添加到已用单元列表中,然后添加

Some minimal Delphi 2009 code to demonstrate the idea. You have to add SyncObjs to the list of used units, and add

  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;

您只需要在问题中添加代码即可。简单地试图释放线程实例会做所有必要的事情来解除线程(如果需要的话)。

You only need to add the code in your question to it. Simply trying to free the thread instance will do everything necessary to unblock the thread (if necessary).

这篇关于如何根据需要启动/停止监控Delphi线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆