.NET Webbrowser Control and Dispose ()

So che questo è un tema molto discusso con molte domande e risposte, ma non trovo ancora la soluzione per il seguente problema:

Ho un’applicazione multi-tab. Su ogni scheda c’è un controllo Webbrowser. Dato che i webbrowser richiedono più memoria per ogni nuova scheda e non liberano questa memoria in tab-close, ho deciso di creare un Webbrowser.Dispose () nel gestore eventi di chiusura della scheda. Questo mi ha aiutato riguardo alla perdita di memoria. tutta la RAM utilizzata è ora gratuita dopo la chiusura.

Ma questo ha causato un nuovo problema: dopo il primo Dispose () sembra che la sessione sia stata distrutta per tutti gli altri oggetti Webbrowser. Normalmente accedo solo al primo browser. Se aggiungo più tabs di solito sono loggato automaticamente. Dopo il primo Dispose () questo non funziona più e devo effettuare il login su ogni nuova scheda.

Ho cercato di conservare i vecchi cookie e di inviarli di nuovo con il nuovo browser ma questo non ha risolto il problema. Il sembra essere distrutto.

Questo sembra essere un problema di GarbageCollector. Puoi provare a usare il modo sporco di System.GC.Collect () , chiamando semplicemente GarbageCollector per liberare memoria, ma questo non è un buon modo per risolvere il problema.

Di quello che hai detto, questo sembra essere un problema di puntatore. Se hai dichiarato la connessione come una variabile globale, devi staccare la connessione dalla scheda prima di poter chiudere / disporre la scheda relativa. L’evento Me.Closing ti può aiutare a farlo. Se il puntatore rimane aperto, la scheda come object è ancora connessa alla connessione e (non propriamente shure se / quando ) non viene pulita dal GC.

Se riesci a chiarire il tuo modo di duplicare / referenziare la connessione, potrei dare una risposta più dettagliata.

EDIT: dopo un po ‘di ricerca le mie preoccupazioni si sono avverate – c’è un problema con il caching sotto IE (> 5 per quanto ne so). http://social.msdn.microsoft.com/Forums/ie/en-US/88c21427-e765-46e8-833d-6021ef79e0c8/memory-leak-in-ie-webbrowser-control

I suggerimenti sono:

  • chiamare manualmente GarbageCollector

  • limitare MemUsage (può causare crash dell’applicazione e anche solo scrivere le pagine su disco)

  • about: blanc per sovrascrivere le voci della cache

  • chiamare i metodi C ++ per sovrascrivere la cache (WinINet – tutto quello che ho trovato è risultato in alcuni errori di ProtectedMemory – forse questo controllo C # WebBrowser: svuota la cache senza che i cookie di cancellazione funzionino )

  • usando C ++ e WinINet (non conosco alcuna implementazione .Net reale e potrebbe anche avere questa perdita di memoria)

  • usando alternative a IE come gecko (Mozilla) – https://bitbucket.org/geckofx/

Tutte le istanze di WebBrowser condividono la sessione in base al processo. Secondo la risposta di EricLaw a una domanda simile, sembra imansible separare le sessioni. Mi fiderei della dichiarazione di Eric mentre lavorava come program manager di IE in Microsoft .

Se tuttavia ti piacerebbe ancora provare alcuni hack, puoi guardare a CoInternetGetSession . Innanzitutto, provare a salvare e conservare il riferimento restituito a IInternetSession . Inoltre, è ansible osservare la registrazione del proprio spazio dei nomi URL ( RegisterNameSpace ) e l’implementazione di un gestore di protocolli collegabile che può eventualmente consentire di annullare questa restrizione.

Certo, suona come un overkill e molto probabilmente non aiuterà affatto. Una soluzione pulita potrebbe essere quella di ridisegnare la logica per sbarazzarsi dei cookie e passare lo stato tramite URL.

MODIFICATO : Un’altra idea, provare a navigare l’istanza WebBrowser per (dire) “circa: vuoto” e attendere l’evento DocumentComplete, prima di smaltirlo con Dispose ().

Grazie per le tue risposte. Ecco cosa ho verificato:

Chiamata GC manualmente:

  • Aiuta solo se utilizzo Webbrowser.Dispose () in precedenza. Ma questa non è una soluzione a causa del problema di sessione.

Limita l’utilizzo di Mem:

  • Non una soluzione Questo programma dovrebbe funzionare per un’intera giornata con molte tabs di apertura e chiusura. Se non riesco a pulire la memoria utilizzata, l’utilizzo della memoria sarà eccessivo dopo alcune ore ..

su bianco:

  • Ho chiamato about: blank on Closing the Tab. Dopo che DocumentLoaded si è verificato per questo URL, ho eliminato il Webbrowser. Stessa procedura della chiamata diretta. La sessione si rompe.

Altri componenti:

  • Ho bisogno di avere un controllo IE in ogni caso perché l’applicazione internet (proprietaria) supporta solo IE 8 e versioni successive.

“Uso di c ++ e WinInet”:

  • Posso usare il browser C ++ nel mio programma .net? Non riesco a passare l’intero programma a C ++. Questa non sarebbe una soluzione per me.

In sintesi:

La mia applicazione funziona bene senza Dispose ma presenta il problema con l’aumento dell’utilizzo della memoria. Se potessimo trovare una soluzione per questo (che sembra imansible) sarebbe la soluzione migliore.

L’unica cosa che sarebbe una soluzione “accettabile” per me è di riutilizzare i browser “chiusi”. In dettaglio: su ogni tab close aggiungo il browser web a una lista invece di eliminarli. Quando ho bisogno di una nuova scheda, prendo il primo della lista e riutilizzandolo e navigo verso il nuovo URL: l’ho provato ma sembra che ci sia lo stesso problema con le sessioni. Le sessioni nelle tabs riutilizzate sembrano essere di nuovo nuove. Ma davvero non capisco perché … Un suggerimento anche per questo?

Un’altra soluzione alternativa consiste nel forzare ogni object Webbrowser a essere una singola istanza. È ansible?