此代码是针对另一个问题建议的解决方案。
当我尝试运行它时,我的代码中的事件没有触发。
循环阻止事件触发。
关于如何避免此问题并允许事件触发的任何建议? 如果删除循环,则事件将按预期触发。 在继续之前,我需要确保事件触发(或超时)。 有什么建议吗?
谢谢。
uses
..., DateUtils, SyncObjs;
type
MyClass = class
private
doneEvent: TEvent;
procedure COMEventHandler(parameters);
procedure Loop(bWait: Boolean);
...
public
constructor Create;
destructor Destroy; override;
procedure DoIt;
end;
constructor MyClass.Create;
begin
inherited;
...
doneEvent := TEvent.Create(True);
end;
destructor MyClass.Destroy;
begin
...
doneEvent.Free;
inherited;
end;
procedure MyClass.COMEventHandler(parameters);
begin
doneEvent.SetEvent;
end;
procedure MyClass.Loop(bWait: Boolean);
var
s: TDateTime;
begin
if not bWait then Exit;
try
doneEvent.ResetEvent;
s := Now;
repeat
case doneEvent.WaitFor(30) of
wrSignaled: begin
// Event fired, all good=> exit
Break;
end;
wrTimeout: begin
if MillisecondsBetween(Now, s) > (1000 * 1000) then
begin
// Timed out=> exit
Break;
end;
if GetQueueStatus(QS_ALLINPUT) <> 0 then
Application.ProcessMessages;
end;
wrError: begin
RaiseLastOSError(doneEvent.LastError);
end;
end;
until False;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end;
procedure MyClass.DoIt;
begin
// invoke COM function that will eventually trigger the COM event...
Loop(True); // wait for event to fire or timer to elapse...
...
end;
答案 0 :(得分:4)
强烈建议您研究以下一个或多个选项,而不是像这样的循环:
TApplicationEvents.OnIdle
TTimer.OnTimer
TThread
,也可以是新的线程方法之一(由于我已经在较早的Delphi版本上完成了大部分的线程工作,所以我还没有自己使用过),答案 1 :(得分:-1)
您的方法基于在MAinThread循环中插入较长的时间。 看一下我的例子:
计时器:
Timer.Interval := <event check timeout>
....
procedure MyClass.OnTimer(Sender: TObject)
begin
case doneEvent.WaitFor(0) of
wrSignaled: ...
wrTimeout: ...
wrError: ...
end
end
线程:
TEventCheckThread = class(TThread)
protected
...
procedure Execute; override;
// Callback to be fired in Main thread if event is OK
procedure ExecuteInMainThread;
...
end;
...
procedure TEventCheckThread.Execute;
begin
while not Terminated do
begin
case doneEvent.WaitFor(TIMEOUT) of
wrSignaled:
begin
Synchronize(ExecuteInMainThread)
end;
wrTimeout: ...
wrError: ...
end
end;
end;
...