2012-03-01 17 views
9

Sto tentando di creare un sistema in delphi che consenta agli utenti di utilizzare Google Maps. Funziona tutto bene, ma sto notando che ogni volta che viene creato un nuovo oggetto TWebBrowser e viene caricato il javascript che gestisce Google Maps, viene generato un numero di nuovi Thread.Javascript in Delphi TWebBrowser, Thread di chiusura

Il mio problema è che anche una volta che il browser viene distrutto (ed è definitivamente distrutto) i thread creati persistono. Sto progettando questo programma per avere lunghi tempi di esecuzione e l'apertura e la chiusura di google maps per accadere molte volte e in quanto tale, dopo un po ', sono stati generati e non terminati così tanti thread che il programma rallenta drasticamente.

C'è qualche modo per distruggere questi thread da solo o sto facendo qualcosa di sbagliato che sta causando la persistenza dei thread?

sto basando il mio programma off del seguente codice:

const 
HTMLStr: AnsiString = 
'<html> '+  
'<head> '+ 
'<meta name="viewport" content="initial-scale=1.0, user-scalable=yes" /> '+ 
'<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true">  </script> '+ 
'<script type="text/javascript"> '+ 
''+ 
''+ 
' var geocoder; '+ 
' var map; '+ 
' var trafficLayer;'+ 
' var bikeLayer;'+ 
' var markersArray = [];'+ 
''+ 
''+ 
' function initialize() { '+ 
' geocoder = new google.maps.Geocoder();'+ 
' var latlng = new google.maps.LatLng(40.714776,-74.019213); '+ 
' var myOptions = { '+ 
'  zoom: 13, '+ 
'  center: latlng, '+ 
'  mapTypeId: google.maps.MapTypeId.ROADMAP '+ 
' }; '+ 
' map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); '+ 
' trafficLayer = new google.maps.TrafficLayer();'+ 
' bikeLayer = new google.maps.BicyclingLayer();'+ 
' map.set("streetViewControl", false);'+ 
' } '+ 
''+ 
''+ 
' function codeAddress(address) { '+ 
' if (geocoder) {'+ 
'  geocoder.geocode({ address: address}, function(results, status) { '+ 
'  if (status == google.maps.GeocoderStatus.OK) {'+ 
'   map.setCenter(results[0].geometry.location);'+ 
'   PutMarker(results[0].geometry.location.lat(),  results[0].geometry.location.lng(),  results[0].geometry.location.lat()+","+results[0].geometry.location.lng());'+ 
'  } else {'+ 
'   alert("Geocode was not successful for the following reason: " + status);'+ 
'  }'+ 
'  });'+ 
' }'+ 
' }'+ 
''+ 
''+ 
' function GotoLatLng(Lat, Lang) { '+ 
' var latlng = new google.maps.LatLng(Lat,Lang);'+ 
' map.setCenter(latlng);'+ 
' PutMarker(Lat, Lang, Lat+","+Lang);'+ 
' }'+ 
''+ 
''+ 
'function ClearMarkers() { '+ 
' if (markersArray) {  '+ 
' for (i in markersArray) { '+ 
'  markersArray[i].setMap(null); '+ 
' } '+ 
' } '+ 
'} '+ 
''+ 
' function PutMarker(Lat, Lang, Msg) { '+ 
' var latlng = new google.maps.LatLng(Lat,Lang);'+ 
' var marker = new google.maps.Marker({'+ 
'  position: latlng, '+ 
'  map: map,'+ 
'  title: Msg+" ("+Lat+","+Lang+")"'+ 
' });'+ 
' markersArray.push(marker); '+ 
' }'+ 
''+ 
''+ 
' function TrafficOn() { trafficLayer.setMap(map); }'+ 
''+ 
' function TrafficOff() { trafficLayer.setMap(null); }'+ 
''+''+ 
' function BicyclingOn() { bikeLayer.setMap(map); }'+ 
''+ 
' function BicyclingOff(){ bikeLayer.setMap(null);}'+ 
''+ 
' function StreetViewOn() { map.set("streetViewControl", true); }'+ 
''+ 
' function StreetViewOff() { map.set("streetViewControl", false); }'+ 
''+ 
''+'</script> '+ 
'</head> '+ 
'<body onload="initialize()"> '+ 
' <div id="map_canvas" style="width:100%; height:100%"></div> '+ 
'</body> '+ 
'</html> '; 


procedure TfrmMain.FormCreate(Sender: TObject); 
var 
    aStream  : TMemoryStream; 
begin 
    WebBrowser1.Navigate('about:blank'); 
    if Assigned(WebBrowser1.Document) then 
    begin 
     aStream := TMemoryStream.Create; 
     try 
    aStream.WriteBuffer(Pointer(HTMLStr)^, Length(HTMLStr)); 
    //aStream.Write(HTMLStr[1], Length(HTMLStr)); 
    aStream.Seek(0, soFromBeginning); 
    (WebBrowser1.Document as IPersistStreamInit).Load(TStreamAdapter.Create(aStream)); 
    finally 
    aStream.Free; 
    end; 
    HTMLWindow2 := (WebBrowser1.Document as IHTMLDocument2).parentWindow; 

end; 
end; 


procedure TfrmMain.ButtonGotoLocationClick(Sender: TObject); 
begin 
    HTMLWindow2.execScript(Format('GotoLatLng(%s,%s)',[Latitude.Text,Longitude.Text]),   'JavaScript'); 
end; 

procedure TfrmMain.ButtonClearMarkersClick(Sender: TObject); 
begin 
    HTMLWindow2.execScript('ClearMarkers()', 'JavaScript') 
end; 

procedure TfrmMain.ButtonGotoAddressClick(Sender: TObject); 
var 
    address : string; 
begin 
    address := MemoAddress.Lines.Text; 
    address := StringReplace(StringReplace(Trim(address), #13, ' ', [rfReplaceAll]), #10, ' ' , [rfReplaceAll]); 
    HTMLWindow2.execScript(Format('codeAddress(%s)',[QuotedStr(address)]),  'JavaScript'); 
end; 

procedure TfrmMain.CheckBoxStreeViewClick(Sender: TObject); 
begin 
    if CheckBoxStreeView.Checked then 
    HTMLWindow2.execScript('StreetViewOn()', 'JavaScript') 
    else 
    HTMLWindow2.execScript('StreetViewOff()', 'JavaScript'); 

end; 

procedure TfrmMain.CheckBoxBicyclingClick(Sender: TObject); 
begin 
    if CheckBoxBicycling.Checked then 
    HTMLWindow2.execScript('BicyclingOn()', 'JavaScript') 
    else 
    HTMLWindow2.execScript('BicyclingOff()', 'JavaScript'); 
end; 


procedure TfrmMain.CheckBoxTrafficClick(Sender: TObject); 
begin 
    if CheckBoxTraffic.Checked then 
    HTMLWindow2.execScript('TrafficOn()', 'JavaScript') 
    else 
    HTMLWindow2.execScript('TrafficOff()', 'JavaScript'); 
end; 


end. 

programma utilizza un distruttore di base che imposta il HTMLWindow per navigare about: blank. Grazie in anticipo

+0

Dove e come distruggi il web browser? – GolezTrol

+0

Il Webbrowser si trova su un TForm gestito da un genitore TForm, distruggo il Child TForm e utilizzo il seguente codice del distruttore: 'destructor TGoogleMap.Destroy; begin HTMLWindow2.navigate ('about: blank'); HTMLWindow2: = nil; WebBrowser1.DestroyComponents; WebBrowser1.Destroy; ereditato fine; ' – user1242937

+4

Per iniziare, il' distruttore' non è necessario. stai facendo una grande insalata lì. il modulo proprietario libererà il 'TWebBrowser' stesso. – kobik

risposta

2

Questo non risponde a questa domanda, semplifica solo il problema da simulare.

Vedere quanti thread è in esecuzione dopo ogni clic del pulsante. Utilizza il Simple Google Maps example, quindi il problema non è nemmeno nella tua parte javascript.

Unit1 - contiene modulo principale, dove è solo un pulsante con gestore di eventi OnClick

unit Unit1; 

interface 

uses 
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
    Dialogs, StdCtrls, PsAPI, TlHelp32, Unit2; 

type 
    TForm1 = class(TForm) 
    Button1: TButton; 
    procedure Button1Click(Sender: TObject); 
    private 
    { Private declarations } 
    public 
    { Public declarations } 
    end; 

var 
    Form1: TForm1; 

implementation 

{$R *.dfm} 

function GetThreadCount(const APID: Cardinal): Integer; 
var 
    NextProc: Boolean; 
    ProcHandle: THandle; 
    ThreadEntry: TThreadEntry32; 
begin 
    Result := 0; 
    ProcHandle := CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); 
    if (ProcHandle <> INVALID_HANDLE_VALUE) then 
    try 
    ThreadEntry.dwSize := SizeOf(ThreadEntry); 
    NextProc := Thread32First(ProcHandle, ThreadEntry); 
    while NextProc do 
    begin 
     if ThreadEntry.th32OwnerProcessID = APID then 
     Inc(Result); 
     NextProc := Thread32Next(ProcHandle, ThreadEntry); 
    end; 
    finally 
    CloseHandle(ProcHandle); 
    end; 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
var 
    ModalForm: TForm2; 
begin 
    ModalForm := TForm2.Create(nil); 
    try 
    ModalForm.ShowModal; 
    finally 
    ModalForm.Free; 
    end; 
    ShowMessage('Thread count: ' + 
    IntToStr(GetThreadCount(GetCurrentProcessId))); 
end; 

end. 

Unit2 - contiene modulo con il TWebBrowser su di esso e gestore di eventi OnCreate del form

unit Unit2; 

interface 

uses 
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
    Dialogs, StdCtrls, OleCtrls, SHDocVw, ActiveX; 

type 
    TForm2 = class(TForm) 
    WebBrowser1: TWebBrowser; 
    procedure FormCreate(Sender: TObject); 
    private 
    { Private declarations } 
    public 
    { Public declarations } 
    end; 

var 
    Form2: TForm2; 

implementation 

{$R *.dfm} 

const 
    HTMLString: AnsiString = 
    '<!DOCTYPE html>' + 
    '<html>' + 
    ' <head>' + 
    ' <title>Google Maps JavaScript API v3 Example: Map Simple</title>' + 
    ' <meta name="viewport"' + 
    '  content="width=device-width, initial-scale=1.0, user-scalable=no">' + 
    ' <meta charset="UTF-8">' + 
    ' <style type="text/css">' + 
    '  html, body, #map_canvas {' + 
    '  margin: 0;' + 
    '  padding: 0;' + 
    '  height: 100%;' + 
    '  }' + 
    ' </style>' + 
    ' <script type="text/javascript"' + 
    '  src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>' + 
    ' <script type="text/javascript">' + 
    '  var map;' + 
    '  function initialize() {' + 
    '  var myOptions = {' + 
    '   zoom: 8,' + 
    '   center: new google.maps.LatLng(-34.397, 150.644),' + 
    '   mapTypeId: google.maps.MapTypeId.ROADMAP' + 
    '  };' + 
    '  map = new google.maps.Map(document.getElementById(''map_canvas''),' + 
    '   myOptions);' + 
    '  }' + 
    '  google.maps.event.addDomListener(window, ''load'', initialize);' + 
    ' </script>' + 
    ' </head>' + 
    ' <body>' + 
    ' <div id="map_canvas"></div>' + 
    ' </body>' + 
    '</html>'; 

procedure TForm2.FormCreate(Sender: TObject); 
var 
    HTMLStream: TMemoryStream; 
begin 
    WebBrowser1.Navigate('about:blank'); 
    if Assigned(WebBrowser1.Document) then 
    begin 
    HTMLStream := TMemoryStream.Create; 
    try 
     HTMLStream.WriteBuffer(Pointer(HTMLString)^, Length(HTMLString)); 
     HTMLStream.Seek(0, soFromBeginning); 
     (WebBrowser1.Document as IPersistStreamInit).Load(TStreamAdapter.Create(HTMLStream)); 
    finally 
     HTMLStream.Free; 
    end; 
    end; 
end; 

end. 
+0

Il problema è relativo al sito di GoogleMaps o in qualsiasi pagina caricata le perdite di TWebBrowser? – EMBarbosa

+1

@EMBarbosa, succede per alcune pagine, ma non per tutte. Quindi non è solo GoogleMaps correlati. – TLama

Problemi correlati