如何启动/停止按需监控德尔福线程?
-
20-09-2019 - |
题
我一直在寻找一种方式来监控在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类,并表示它已设置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;
您只需要在你的问题,将其添加的代码。只是试图释放线程实例将采取一切必要行动,以解除阻塞线程(如有必要)。
其他提示
而不是无限你应该有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;
不隶属于 StackOverflow