我知道Delphi線程已經在很多線程上討論過了。我試着審查他們,但沒有找到我的問題的答案。這個Delphi線程代碼是否正確?
背景: 我發現在瀏覽器加載Adobe Acrobat Reader DC後,釋放TWebBrowser可能需要10多秒。我想不知何故它正在檢查更新或其他內容。嘗試使用瀏覽器關閉表單時很煩人。
我想也許我可以有一個後臺線程釋放瀏覽器。所以我將瀏覽器變量移動到一個全局變量(私人存儲在單元的實現部分)。一次只能使用其中一種形式。然後我試圖在後臺釋放一個線程。它沒有按我的預期工作。
實施例代碼
interface
TMyform = class(TForm)
pnlBowserHolder: TPanel;
procedure FormDestroy(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
//WebBrowser : TWebBrowser; <-- moved to global variable
public
{ Public declarations }
end;
implementation
type
TBackgroundBrowserKillerThread = class(TThread)
public
procedure Execute; override;
end;
var
WebBrowser : TWebBrowser;
BrowserKillerThread : TBackgroundBrowserKillerThread;
procedure TfrmLabImageViewer.FormCreate(Sender: TObject);
begin
WebBrowser := TWebBrowser.Create(Self);
TWinControl(WebBrowser).Parent := pnlBowserHolder;
WebBrowser.Align := alClient;
end;
procedure TfrmLabImageViewer.FormDestroy(Sender: TObject);
begin
BrowserKillerThread := TBackgroundBrowserKillerThread.Create(true);
Application.ProcessMessages;
BrowserKillerThread.Execute();
//WebBrowser.Free;
end;
procedure TBackgroundBrowserKillerThread.Execute();
begin
TWinControl(WebBrowser).Parent := nil;
FreeAndNil(WebBrowser);
self.FreeOnTerminate := true;
BrowserKillerThread := nil; //free reference to thread, shouldn't affect ability of self to free itself (?)
end;
問題:
- 當我通過在調試模式下FormDestroy碼步驟,含有BrowserKillerThread.Execute線();需要10秒鐘才能執行。我以爲這會啓動另一個線程並立即返回。但事實並非如此。我對執行程序的理解錯誤嗎?還是有趣的事情呢?
- 我在做什麼壞事?我已經讀過VCL不是線程安全的,並且不能/不應該從另一個線程訪問VCL對象。我希望這不適用於這種情況,因爲我只是在沒有進一步交互計劃的情況下釋放對象。
- 如果一個線程在終止時爲空,我認爲這會讓我的BrowserKillerThread指針懸空。那麼,我可以像這樣分配nil嗎?
- 有關如何做得更好的建議?
非常感謝。
KT
這是永遠不會工作。除了主線程之外,您無法從任何地方訪問任何類型的VCL控件,也無法在一個線程中創建它並在另一個線程中銷燬它。你寫的代碼不會改變任何東西 - 瀏覽器仍然被擁有它的主線程破壞;你只是從你的線程調用該代碼(除非你通過Synchronize來完成,否則這是錯誤的)。 –
另外...您可能想要再次查看所有這些線程。我敢打賭,你還沒有看到過一個例子有從外部調用的執行方法。爲什麼?因爲那麼execute方法中的代碼將在調用它的線程的上下文中運行。 –
我不會因使用Acro Reader DC的TWebBrower + v.15.023而導致關閉應用程序的延遲。你能給一個例子的網址,引發你的延遲? – MartynA