0
誰能告訴我爲什麼這段代碼導致我的應用程序停止響應。定時器導致鎖
我的應用程序調用一個COM庫。我等待COM庫事件觸發,以便繼續。 我用一個定時器,以保持檢查是否COM庫解僱:
procedure MyTimer(hWnd: HWND; uMsg: Integer; idEvent: Integer; dwTime: Integer); stdcall;
begin
//writeln('Timer Event');
end;
我繼續檢查,如果觸發的事件是這樣的:
procedure MyClass.Loop(bwait: boolean);
var
s: TDateTime;
id: uint;
begin
try
id := SetTimer(0, 1, 1000, @MyTimer);
s := Now;
while bwait do
begin
sleep(30);
Application.ProcessMessages;
if bwait = false then // Event fired, all good=> exit
begin
KillTimer(0, id);
break;
end;
if Now - s > EncodeTime(0, 0, 1000, 0) then // Timed out=> exit
begin
KillTimer(0, id);
break;
end;
end;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end;
當COM庫事件觸發其設置BWAIT布爾變量這意味着一切都很好,我們可以退出並繼續前進。
如果事件未在一定時間內觸發,則退出&通知用戶。
此代碼有時會創建線程鎖。
我的應用程序和COM庫停止響應。 什麼導致鎖?
上述代碼如何改進?
謝謝。
沒有更多的COM庫知識,線程模型等,很難說。當然,這個問題中的代碼看起來非常可疑,從調用Sleep和Application.ProcessMessages開始。 –
我在我的應用程序中沒有使用線程。 COM庫可能在內部使用線程,但我不知道。 不需要Application.ProcessMessages來檢查我的bwait變量是否已由COM庫事件設置? 我會嘗試沒有睡眠和Application.ProcessMessages的代碼。 謝謝 –
不要嘗試使用異步模型編寫同步代碼。使用活動的重點在於你應該繼續做你喜歡的任何事情;然後在事件發生時處理。嘗試撤消它會拋出所有的好處,並強迫你阻止你的代碼,直到你收到一些特定的事件...如果你沒有收到它,會發生什麼? _鎖死了!_ –