2015-04-15 4 views
5

Ho passato gli ultimi giorni cercando in quella e io non riesco a capirlo.perdita di memoria CrystalReports ReportDocument con connessioni al database

Ho un'applicazione c#WinForms che utilizza il ReportDocument per caricare un report e metterlo in Viewer Crystal Report, in modo che l'utente possa visualizzarlo in anteprima. Lo scopo è di visualizzare un'anteprima di statistiche diverse e il modulo non viene mai chiuso. C'è un timer che viene eseguito e carica diversi report nel visualizzatore.

Mentre ciò accade l'utilizzo della memoria e le maniglie (Li vedo nel task manager) continuare ad aumentare. Quando l'applicazione viene avviata, utilizza circa 30 MB e quando viene eseguita per 10 minuti, utilizza circa 200 MB e continua ad aumentare.

Ho letto molto su questo problema su Internet e ho trovato che sia il ReportDocument sia il Viewer devono essere chiusi e smaltiti. Sfortunatamente, questo non lo risolve. Il tipo di connessione nei report è OLE DB(ADO) quando i dati vengono recuperati da un database SQL Server.

In breve, ciò che accade è che Form1 dispone di un timer che, una volta trascorso, dispone di Crystal Reports Viewer e chiama il garbage collector. E poi carica il nuovo report.

Ecco il codice di esempio che ho

Form1:

private ReportDocument rpt; 

private void timer2_Tick(object sender, EventArgs e) 
{ 
    timer2.Enabled = false; 

    try 
    { 
      panel1.Hide(); 

      if (rpt != null) 
      { 
       foreach (Table t in rpd.Database.Tables) 
         t.Dispose(); 
       rpt.Close(); 
       rpt.Dispose(); 
       rpt = null; 
       GC.Collect(); 
      } 

      panel1.Controls.Remove(CRVviewer); 
      if (CRVviewer != null) 
      { 
       CRVviewer.Dispose(); 
       GC.Collect(); 
      } 

      // The problem starts from here: 

      var report = navigationbar1.CurrentNode; 
      rpt = new ReportDocument(); 
      rpt.Load(@report.Path, OpenReportMethod.OpenReportByDefault); 

      rpt.ReportOptions.EnableSaveDataWithReport = false; 

      rpt.SetDatabaseLogon(report.UserId, report.Password); 

      rpt.VerifyDatabase(); 

      // It ends here 

      CRVviewer = new CrystalReportViewer(); 
      CRVviewer.ReportSource = rpt; 
      CRVviewer.ShowLastPage(); 
      pagecount = CRVviewer.GetCurrentPageNumber(); 
      CRVviewer.ShowFirstPage(); 
      panel1.Controls.Add(CRVviewer); 
      this.Update(); 
    } 
    catch(Exception ex) 
    { 
     ProcessErrors(ex); 
    } 
    finally 
    { 
     timer2.Enabled = true; 
    } 
} 

Il problema viene dalle connessioni DB, perché se carico un report locale, funziona benissimo. Ma cosa faccio di sbagliato?

risposta

7

È molto difficile con Crystal Report per pulire il disordine creato con la memoria. (Senza offesa per SAP)

Si dovrà prima chiusura e smaltire il ReportDocument

rpt.Close(); 
rpt.Dispose(); 

e quindi assegnare i null al ReportViewer e smaltire.

CRViewer.ReportSource=null; 
CRViewer.Dispose(); 
CRViewer=null; 

Infine, è necessario eseguire due passaggi GC.

GC.Collect(); 
GC.WaitForPendingFinalizers(); 
GC.Collect(); 

prega di notare che non è generalmente consigliato di chiamare GC.Collect(), ma a volte quando la memoria è troppo di un problema e di come terzo rapporto di cristallo componente COM partito ha problema con ottenere smaltiti correttamente, potrebbe dover percorrere questa strada.

+0

Grazie, l'utilizzo della memoria sembra andare bene ora, ma le maniglie nel task manager continuano ad aumentare. – Apostrofix

+0

EDIT: E dopo ulteriori test, l'utilizzo della memoria è ancora in aumento. – Apostrofix

+1

Si potrebbe desiderare di provare profiler memoria come [dotMemory] (https://www.jetbrains.com/dotmemory/) Questo non è facile da usare e hanno 5 giorni di prova gratuita. Ho risolto il mio problema di memoria con l'aiuto di questo strumento quando avevo problemi di memoria in modo simile con i report Crystal. Inoltre, vuoi anche tenere d'occhio tutti gli eventi sottoscritti ricevendo correttamente non abbonati, specialmente se hai qualche referto di cristallo in quegli eventi. Proverò a eseguire il tuo codice e vedere se riesco a trovare altri problemi? è questo il codice completo? – ANewGuyInTown