Обновлять TWebBrowser в отдельной теме? - PullRequest
21 голосов
/ 02 марта 2012

Я использую TWebBrowser, чтобы показать карту Google.Проблема в том, что он блокирует основной поток пользовательского интерфейса во время загрузки карты.Возможно ли обновить карту в отдельном потоке?

Редактировать: RRUZ Вы правы. TWebBrowser имеет асинхронную загрузку для URL.Но я нашел проблему, почему он блокирует вызов:

if WaitWhileProcessing and (MapQueryResult.Count > 0) then 
  Result := MapQueryResult[0] as TMapQuery;

и метод:

function TMapItemCollection.WaitWhileProcessing: Boolean;
var
  vMaxSleepCnt: Integer;
begin
  Result := True;
  vMaxSleepCnt := 0;
  while Processing or Loading do
  begin
    inc(vMaxSleepCnt);
    Application.ProcessMessages;
    Sleep(100);
    if vMaxSleepCnt = 100 then
    begin
      Result := False;
      Break;
    end;
  end;
end;

Так что, кажется, это исправить, код должен быть реорганизован.Но это не сфера для этого вопроса.

1 Ответ

3 голосов
/ 27 апреля 2012

Когда оператор if выполняется и вызывает WaitWhileProcessing для оценки условия, он повторяется 100 раз с 10-й секунды сна.Но какие сообщения ожидают при вызове ProcessMessages?Может ли метод быть вызван снова рекурсивно?Он никогда не заснет, но продолжает вызывать этот метод.Кстати, имейте в виду, что ProcessMessages действительно плохая практика, но сейчас ... попробуйте это:

var
  isWaitWhileProcessingBusy :boolean = false;

function TMapItemCollection.WaitWhileProcessing: Boolean;
var
 vSleepCnt: Integer;
begin      
  if not isWaitWhileProcessingBusy then
  begin
    isWaitWhileProcessingBusy = true;
    vSleepCnt := 0;
    while Processing or Loading or vSleepCnt < 100 do
    begin
      inc(vSleepCnt);
      Application.ProcessMessages;
      Sleep(100);
    end;
    isWaitWhileProcessingBusy := false;
  end;
  Result = Processing or Loading;
end;

Как вы можете видеть, я также изменил некоторые другие мелочи.Разрыв не находится в состоянии while, а результат является просто результатом обработки или загрузки (потому что это выражение дает фактический результат).Дополнительный isWaitWhileProcessingBusy вне функции предотвращает повторный ввод цикла сообщений.Надеюсь, это предотвратит блокировку пользовательского интерфейса.Это также не лучшая практика, но на данный момент это может помочь решить проблему и точно определить проблему.

Есть ли причина, по которой вы запрашиваете информацию о загрузке / обработке?Разве не было бы намного проще использовать событие TWDBrowser OnDocumentComplete?

... и мне в голову пришла еще одна мысль ... Вы проверили диспетчер задач?Google Maps использует Flash, компонент ActiveX также использует основной поток пользовательского интерфейса.Это также может быть источник ресурсов, вызывающий голод.

Удачи!

...