當你在aTFrame并且你做的時候,你TThread.ForceQueue(nil, MyFrame.OneProc, 200)如何檢查同時沒有被破壞的MyFrame.OneProc程式MyFrame?
換句話說,在這種常見的場景中可以使用什么機制?
uj5u.com熱心網友回復:
您可以使用監護人介面,該介面將是功能齊全的實體,您可以使用它來檢查在此期間是否釋放了受保護的物件。
type
IGuardian = interface
function GetIsDismantled: Boolean;
procedure Dismantle;
property IsDismantled: Boolean read GetIsDismantled;
end;
TGuardian = class(TInterfacedObject, IGuardian)
private
FIsDismantled: Boolean;
function GetIsDismantled: Boolean;
public
procedure Dismantle;
property IsDismantled: Boolean read GetIsDismantled;
end;
procedure TGuardian.Dismantle;
begin
FIsDismantled := True;
end;
function TGuardian.GetIsDismantled: Boolean;
begin
Result := FIsDismantled;
end;
然后你需要在你的框架中添加監護人欄位
type
TMyFrame = class(TFrame)
private
FGuardian: IGuardian;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
property Guardian: IGuardian read FGuardian;
end;
constructor TMyFrame.Create(AOwner: TComponent);
begin
inherited;
FGuardian := TGuardian.Create;
end;
destructor TMyFrame.Destroy;
begin
// prevent AV when destroying partially
// constructed instance
if Assigned(FGuardian) then
FGuardian.Dismantle;
inherited;
end;
但是你不能直接對 frame 進行排隊MyProc,你需要使用匿名方法并捕獲那個守護變數,這樣它的生命就會延長到幀的生命周期之外。
即使在MyFrame釋放后,參考計數也會使守護物件實體保持活動狀態,并且其記憶體將被自動管理。
重要的是使用本地宣告的Guardian介面變數并捕獲該變數而不是直接捕獲MyFrame.Guardian欄位,因為該欄位地址在MyFrame被釋放后將不再有效。
procedure CallMyProc;
var
Guardian: IGuardian;
begin
Guardian := MyFrame.Guardian;
TThread.ForceQueue(nil,
procedure
begin
if Guardian.IsDismantled then
Exit;
MyFrame.OneProc;
end, 200);
end;
注意:即使您立即使用TThread.Queue,也有可能在排隊程式運行之前釋放幀。所以你需要保護你的框架也是這種情況。
uj5u.com熱心網友回復:
您不能在已銷毀的物件上呼叫方法。在優選的解決方案是簡單地從佇列中移除的方法,如果它沒有被呼叫的是,之前銷毀物件。TThread有一個RemoveQueuedEvents()方法可以達到這個目的。
例如:
TThread.ForceQueue(nil, MyFrame.OneProc, 200);
...
TThread.RemoveQueuedEvents(MyFrame.OneProc);
MyFrame.Free;
或者,改用框架的解構式:
TThread.ForceQueue(nil, MyFrame.OneProc, 200);
...
destructor TMyFrame.Destroy;
begin
TThread.RemoveQueuedEvents(OneProc);
inherited;
end;
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/353709.html
標籤:德尔福
上一篇:Delphi記錄賦值
下一篇:在CSV列中減去兩個日期時間
