我创建了一个测试html页面,它有一个阻塞循环。当我调用TWebBrowser.Navigate()
时,主线程挂起。但据说TWebBrowser
异步工作。看起来不是这样!
这是一个简单的html文件
<html>
<title>test</title>
<script type="text/javascript">
var i = 0;
function writeIt() {
i++;
var start = Date.now();
var element = document.getElementById("test");
if (element) {
while (Date.now() < start + 15000) {
element.innerHTML = i;
i++;
}
}
}
function startIt() {
writeIt();
//setTimeout(writeIt, 1000);
}
//window.onload=startIt();
</script>
<body>
<div id="test"></div>
<script>
startIt();
</script>
</body>
</html>
项目展示:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.OleCtrls, SHDocVw,
Vcl.ExtCtrls;
type
TForm1 = class(TForm)
WebBrowser1: TWebBrowser;
Button1: TButton;
FileOpenDialog1: TFileOpenDialog;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
if FileOpenDialog1.Execute then
WebBrowser1.Navigate(FileOpenDialog1.FileName);
end;
end.
在此html文件上调用WebBrowser1.Navigate()
后,主线程挂起15秒。
是否有任何解决方案可以阻止TWebBrowser
阻止主线程?
更新:
似乎Javascript在BeforeScriptExecute
事件被触发后立即开始锁定线程。如果我在这里使用Application.ProcessMessages()
,Javascript永远不会执行。我仍在努力寻找解决方案来解决这个问题。
答案 0 :(得分:2)
你无能为力,这不是Delphi问题,而是IE问题(TWebbrowser
是IE的ActiveX浏览器控件的薄包装)。
对Navigate的调用将阻止,直到javascript被执行。
在Internet Explorer中测试您的文件,您将看到IE没有响应。
唯一的出路是使用基于Chromium / DCEF的解决方案或move the TWebbrowser in its own process/thread。