Tuesday, April 3, 2012

Crystal Reports: The maximum report processing jobs limit configured by your system administrator has been reached.

This exception is produced by Crystal Reports when the maximum number of concurrent report processes have been initiated. I have had troubles with this exception in my asp.net application, but at first it seemed almost to occur at random. Recycling the app pool solved the problem when it occurred. After a while (when the application was used more intensively) this became a real problem, as it began to occur more and more often.

My application does not use a ReportViewer, but rather generates a pdf file and sends it to the client as a download, using the following code:
ReportDocument repDoc = new ReportDocument();

repDoc.Load(filename);
// update the crystal report database connection
repDoc.SetCrystalReportDatabase("ConnectionString");

// send the resulting document to the user (as PDF).
Response.ClearContent();
Response.ClearHeaders();

repDoc.ExportToHttpResponse(formatType, Response, true"Report");

repDoc.Dispose();

At first, I fixed this problem quite easily, by altering one value in the registry:

HKEY_LOCAL_MACHINE\SOFTWARE\Business Objects\Suite 11.5\Report Application Server\InprocServer\PrintJobLimit
It is set to 75 by default, I set it to 250. (Use regedit.exe to change this, but be careful, you can really mess up Windows if you make mistakes while altering the registry!)


But after some time (when the application was used even more intensively) the problem returned, so I looked into it again and started looking for a more definite solution.


I found that for some reason the Dispose(); in my code did not get called properly (I think the ExportToHttpResponse call throws an exception, although I did not check this).
When I changed the code to:
using(ReportDocument repDoc = new ReportDocument())
{
   repDoc.Load(filename);
   // update the crystal report database connection
   repDoc.SetCrystalReportDatabase("ConnectionString");

   // send the resulting document to the user (as PDF).
   Response.ClearContent();
   Response.ClearHeaders();

   repDoc.ExportToHttpResponse(formatType, Response, true"Report");

}
The problem was fixed ... at least for now.

I have also found out that if you use a viewer, you will have to maintain a reference to the ReportDocument in a private variable on your page. In the Page_Unload() event, you can then close and dispose of this object, so that it is cleared from memory, like so:
class MyPage Page
{
    private ReportDocument repDoc = null;
    Page_Load(object sender, EventArgs e)
    {
        this.repDoc = new ReportDocument();
        this.viewer.ReportSource = repDoc;
    }


    Page_Unload(object sender, EventArgs e)
    {
        if(this.repDoc != null)
        {
            this.repDoc.Close();
            this.repDoc.Dispose();
        }
    }
}

No comments:

Post a Comment