2012-03-01 4 views
21

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

Редактировать: 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; 

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

+3

Вы уверены, что графический интерфейс frezees во время загрузки карты? потому что TWebBrowser действует асинхронно. можете ли вы показать код, который вы используете для загрузки карты? – RRUZ

+0

Вы пробовали это с помощью TEmbeddedWB от www.bsalsa.com? У него может быть решение уже, и его довольно легко переключить на него и заставить работать асинхронные нагрузки. –

+0

Спасибо за предложения как RRUZ, так и WarrenP. RRUZ правы, что это уже асинхронная загрузка в TWebBrowser. Так что в моем случае причина - это что-то другое. Я должен исследовать, потому что код довольно сложный ... –

ответ

3

Когда выполняется оператор 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 вне функции сохраняет повторный ввод цикла сообщения. Надеемся, что это предотвратит блокировку пользовательского интерфейса. Это также не лучшая практика, но на данный момент это может помочь решить проблему, и с ней точно определить проблему.

Есть ли причина, по которой вы опросили Loading/Обработка? Не было бы намного проще использовать событие OnDocumentComplete для TWebBrowser?

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

Удачи вам!

Смежные вопросы