Вопрос, поднятый в этой статье, касается проблемы блокировки основного потока программы при использовании компонента TWebBrowser в среде разработки Delphi для загрузки HTML-страницы с бесконечным JavaScript-циклом. Несмотря на то, что TWebBrowser позиционируется как асинхронный, на практике это не так, и основной поток блокируется, что приводит к зависанию программы.
Описание проблемы
Разработчик столкнулся с проблемой, когда при загрузке HTML-страницы с бесконечным циклом в JavaScript через компонент TWebBrowser основной поток программы блокируется на время выполнения скрипта. Это происходит, несмотря на то, что ожидается асинхронное поведение TWebBrowser. Проблема была воспроизведена на простом примере HTML-страницы с JavaScript-циклом, который выполняется в течение 15 секунд.
Пример 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>
Пример проекта на Delphi
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.
При вызове WebBrowser1.Navigate() на указанной HTML-странице основной поток замораживается на 15 секунд.
Возможные решения
Проблема заключается в том, что TWebBrowser использует ActiveX-контрол интернет-эксплорера, который не работает асинхронно и блокирует основной поток при выполнении JavaScript. Существуют следующие варианты решения:
Использование компонентов на основе Chromium или DCEF, которые не имеют подобных ограничений.
Перемещение TWebBrowser в отдельный процесс, что позволит избежать блокировки основного потока. Это может быть реализовано с помощью ActiveX-DLL или отдельного EXE.
Использование нескольких экземпляров TWebBrowser в разных потоках.
Подтвержденный ответ
К сожалению, нет простого решения, которое позволит избежать блокировки основного потока без изменений в архитектуре приложения. Разработчики, столкнувшиеся с этой проблемой, рекомендуют использовать компоненты на основе Chromium или переместить TWebBrowser в отдельный процесс.
Альтернативный ответ
Некоторые разработчики отмечают, что даже использование Chromium не гарантирует отсутствие блокировки основного потока, так как поведение может зависеть от конкретного кода. Перемещение TWebBrowser в отдельный процесс, хотя и является технически возможным, может быть неэффективным решением из-за сложности реализации и дополнительных затрат на ресурсы.
Заключение
Проблема блокировки основного потока при использовании TWebBrowser с бесконечным JavaScript-циклом является известной и связана с ограничениями, наложенными на ActiveX-контрол интернет-эксплорера. Для решения этой проблемы рекомендуется перейти на использование компонентов, не зависящих от интернет-эксплорера, или же применять сложные архитектурные решения, такие как запуск TWebBrowser в отдельном процессе.
Проблема связана с блокировкой основного потока программы при использовании компонента TWebBrowser в Delphi из-за бесконечного JavaScript-цикла на загружаемой странице.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.