2012-03-01 15 views
21

Używam TWebBrowser do wyświetlania mapy Google. Problem polega na tym, że blokuje główny wątek interfejsu użytkownika podczas ładowania mapy. Czy można aktualizować mapę w osobnym wątku?Zaktualizuj TWebBrowser w osobnym wątku?

Edytuj: RRUZ masz rację TWebBrowser ma asynchroniczne ładowanie dla adresu URL. Ale znalazłem problem dlaczego blokuje połączenia:

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

i metoda:

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; 

Wygląda więc na to, aby naprawić ten kod powinien być refactored. Ale to nie jest zakres tego pytania.

+3

Czy jesteś pewien, który GUI frezees podczas ładowania mapy? ponieważ TWebBrowser działa asynchronicznie. czy możesz pokazać kod, którego używasz do załadowania mapy? – RRUZ

+0

Czy próbowałeś z TEmbeddedWB z www.bsalsa.com? Może mieć już rozwiązanie i być całkiem łatwe do przełączenia się do niego i uzyskania działania obciążeń asynchronicznych. –

+0

Dzięki za sugestie zarówno RRUZ, jak i WarrenP. RRUZ mają rację, że jest już ładowanie asynchroniczne w TWebBrowser. W moim przypadku powodem jest coś innego. Muszę zbadać, ponieważ kod jest dość skomplikowany ... –

Odpowiedz

3

Po wykonaniu instrukcji if i wywołaniu WaitWhileProcessing w celu oceny warunku, pętla wykonuje się 100 razy z 10-sekundowym snem. Ale jakie wiadomości oczekują podczas wywoływania ProcessMessages? Czy metodę można nazwać ponownie rekursywnie? Nigdy nie zasypia, ale powtarza tę metodę. Nawiasem mówiąc, należy pamiętać, że ProcessMessages jest naprawdę zła praktyka, ale teraz ... spróbuj tego:

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; 

Jak widać ja też zmienić kilka innych drobnych rzeczy. Przerwa nie występuje w warunku while, a wynik jest po prostu wynikiem przetwarzania lub ładowania (ponieważ wyrażenie to daje rzeczywisty wynik). Dodatkowa funkcjaWaitWhileProcessingBusy poza funkcją zapobiega ponownemu wprowadzaniu pętli komunikatów. Mam nadzieję, że to uniemożliwi zablokowanie interfejsu użytkownika. Nie jest to również najlepsza praktyka, ale na razie może pomóc w rozwiązaniu problemu, a wraz z nim wskazać problem.

Czy istnieje powód, dla którego sondujesz Ładowanie/przetwarzanie? Czy nie byłoby o wiele łatwiej używać zdarzenia OnDocumentComplete TWebBrowser?

... i inna myśl przyszła mi do głowy ... Czy sprawdziłeś menedżera zadań? mapy google używają flasha, komponentu activex również używającego głównego wątku UI. Może to być również świnia zasobów powodująca głód.

Powodzenia!