Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Windows/Temp folder fast filling with Crystal files

Status
Not open for further replies.

pontupo

Technical User
Jul 9, 2007
33
US
So the Windows/Temp folder is fast filling the disk in my deployment. Each time a report is opened, a number of files are created here. The problem is, of course, probably that I'm not releasing my report objects in my code, as these files can't even be manually deleted without shutting down IIS. Well, fair enough. What I can't figure out is where to release my reports.

I have two pages: one performs a pre-pass of the report object and generates a dynamic page to prompt the user for parameters. This page, I believe, has no problems because the report.Close() command is in line with the code and is the final statement. The second page, however, has the CrystalReportsViewer object and actually displays the report to the user after setting up the parameters correctly. On this page, I can't figure out how/when to call report.Close(). If I do it at the page.Dispose event, there seems to be no affect. If I do it at the page.Close event, the report will load fine, but if you try to go to another page in the report (in the case of multi-page reports) or refresh the data, the report object has already been unloaded and the CrystalReportsViewer won't be able to find the report document. If I wrap my code in one big Try-Catch-Finally (rather than just having a Try-Catch around the file load itself) and place a report.Close() command in the Finally, the Finally is executed before the viewer even loads the report so I get a file not found error.


So where can I unload the report object? What I want is to persist the report via Sessions (which I do) so that as the user moves between pages of the report/refreshes the report will remain loaded, but when the user closes the page or browses to another page, perhaps, I want to close the report and free the resources so that the temp files are deleted. I can post my code if needed... Thanks in advance,
Pont
 
You don't mention what language your application is written in...

In ASP.Net with C# for the code-behind, we use the following code to close the data connections and delete the temp files:
Code:
  private void Page_Unload(object sender, EventArgs e)
  {
    CloseReports(crReport);
    crystalReportViewer.Dispose();
    crystalReportViewer = null;
  }


  private void CloseReports(ReportDocument reportDocument)
  {
    Sections sections = reportDocument.ReportDefinition.Sections;
    foreach (Section section in sections)
    {
      ReportObjects reportObjects = section.ReportObjects;
      foreach (ReportObject reportObject in reportObjects)
      {
        if (reportObject.Kind == ReportObjectKind.SubreportObject)
        {
          SubreportObject subreportObject = (SubreportObject)reportObject;
          ReportDocument subReportDocument = subreportObject.OpenSubreport(subreportObject.SubreportName);
          subReportDocument.Close();
        }
      }
    }
    reportDocument.Close();
  }

This clears the tempfiles and releases the memory. I realize that .NET does a lot of memory management automatically, but because the .NET API is a wrapper for COM objects, the "best practice" is to explicitly Dispose them.

-Dell

A computer only does what you actually told it to do - not what you thought you told it to do.
 
Thanks very much for the quick reply! I'm using VB, but the code you posted is easily translatable. I think my mistake is likely in part due to my not closing out subreports. Most of the reports in my distribution don't have subreports, but the few that do tend to have either a large number of subreports, many calls to subreports, or both.

I'm not sure that I tried the unload event either.

I'll try to implement this and see if it helps. Thanks again
 
Hmm, I tried it out and still no luck. What happens with the page_unload event is that it is called on each page transition within the report. So, if the user tries to navigate to page two of the report, an Invalid File Path error is generated as the report document has already been closed out. I'm beginning to wonder if I'm having problems with my Session persistence rather than the unloading of the report Objects. I'll post the relevant bits of my code tomorrow to see if anyone can see an obvious problem.

 
Here's the relevant code:
Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
sessionString = Request.QueryString("report")
report = Server.MapPath("reports/") & Request.QueryString("report") & ".rpt"
ConfigureCrystalReport()
End Sub

Private Sub ConfigureCrystalReport()
If (Session(sessionString) Is Nothing) Then
reportDoc = New ReportDocument()
'load the report document
If (IsReportValid()) Then
reportDoc.Load(report)
'******************************
'bunch of other code, authentication
'parameter handling, etc. here
'******************************
Session(sessionString) = reportDoc
Else
Response.Redirect("error.aspx")
End If
Else
reportDoc = CType(Session(sessionString), ReportDocument)
End If
CrystalReportsViewer.ReportSource = reportDoc
End Sub

Private Function IsReportValid() As Boolean
Dim reportIsValid As Boolean = False
Try
If (System.IO.File.Exists(report)) Then 'does the file exist?
'if it does, try to load it to confirm it's a valid crystal report
Dim tryReportLoad As New CrystalDecisions.CrystalReports.Engine.ReportDocument()
tryReportLoad.Load(report)
tryReportLoad.Close()
tryReportLoad.Dispose()
reportIsValid = True
End If
Catch ex As Exception
reportIsValid = False
End Try

Return reportIsValid
End Function


Currently, I've also tried each of the following:
Protected Sub Page_Unload(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Unload
CloseReports(reportDoc)
CrystalReportsViewer.Dispose()
CrystalReportsViewer = Nothing
End Sub

Private Sub CloseReports(ByVal report As ReportDocument)
Dim sections As Sections = report.ReportDefinition.Sections
For Each section As Section In sections
Dim reportObjects As ReportObjects = section.ReportObjects
For Each reportObject As ReportObject In reportObjects
If (reportObject.Kind = ReportObjectKind.SubreportObject) Then
Dim subreportObject As SubreportObject = CType(reportObject, SubreportObject)
Dim subReportDoc As ReportDocument = subreportObject.OpenSubreport(subreportObject.SubreportName)
subReportDoc.Close()
End If
Next
Next
report.Close()
End Sub

That one as suggested yesterday and also:
Protected Sub Page_Disposed(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Disposed
reportDoc.Close()
reportDoc.Dispose()
CType(Session(sessionString), ReportDocument).Close()
Session(sessionString) = Nothing
End Sub

I've also tried wrapping everything inside of the If statement in the ConfigureCrystalReport() method in code to this effect:
If (IsReportValid()) Then
Try
reportDoc.Load(report)
Catch e As Exception
Response.Redirect("error.aspx")
Finally
reportDoc.Close()
End Try


So far, none of these techniques have been able to both persist the report object across the natural user actions of page-switching, refreshing the report, etc. through use of the CrystalReportsViewer built in buttons, but also allow me to unload and dispose of the objects when the user closes the window or navigates to another page.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top