我一直在寻找一种方法来监视Delphi中特定的注册表更改。在about.com上找到了solution:
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;
您只需要在问题中添加代码即可。只需尝试释放线程实例即可完成解除线程阻塞的所有必要操作(如有必要)。
关于multithreading - 如何按需启动/停止监视Delphi线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1734644/