問題是您的代碼沒有保留由AsyncCall
函數返回的IAsyncCall
接口。
AsyncCall(@Load, []);
//AsyncCall returns an IAsyncCall interface,
//but this code does not take a reference to it
因此,一旦初始化部分完成,返回的接口將其引用計數遞減爲零。因此這釋放了實現該執行此界面上的對象:
destructor TAsyncCall.Destroy;
begin
if FCall <> nil then
begin
try
--> FCall.Sync; // throw raised exceptions here
finally
FCall.Free;
end;
end;
inherited Destroy;
end;
關鍵線是這迫使被執行以完成異步調用Sync
呼叫。所有這些都發生在解釋你報告行爲的主線程中。
的解決方案是,你只需要保持IAsyncCall
接口活活將其存儲在一個變量。
var
a: IAsyncCall;
initialization
a := AsyncCall(@Load, []);
在您需要確保Load
已運行是Load
依賴任何代碼前完成真正的代碼。當您的程序達到要求撥打Load
的點時,必須在IAsyncCall
接口上撥打Sync
。
所以你可能會寫這樣的東西。
unit MyUnit;
interface
procedure EnsureLoaded;
implementation
uses
AsyncCalls;
....
procedure Load;
begin
....
end;
var
LoadAsyncCall: IAsyncCall;
procedure EnsureLoaded;
begin
LoadAsyncCall := nil;//this will effect a call to Sync
end;
initialization
LoadAsyncCall := AsyncCall(@Load, []);
end.
從其他單位所需Load
有運行調用EnsureLoaded
。或者,可以從MyUnit
導出的任何方法調用EnsureLoaded
,這些方法依賴Load
運行。後面的選項有更好的封裝。
沒有。不工作。即使我把它從初始化中刪除,但在某個虛擬按鈕上加載過程。 – 2012-01-10 19:33:40