在导航阻塞html期间,TWebBrowser挂起主线程

时间:2018-01-23 10:04:57

标签: delphi webbrowser-control twebbrowser

我创建了一个测试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永远不会执行。我仍在努力寻找解决方案来解决这个问题。

1 个答案:

答案 0 :(得分:2)

你无能为力,这不是Delphi问题,而是IE问题(TWebbrowser是IE的ActiveX浏览器控件的薄包装)。 对Navigate的调用将阻止,直到javascript被执行。 在Internet Explorer中测试您的文件,您将看到IE没有响应。 唯一的出路是使用基于Chromium / DCEF的解决方案或move the TWebbrowser in its own process/thread