Solved

asp.net usage of web viewer and postback problems

Posted on 2006-11-20
10
4,969 Views
Last Modified: 2008-01-09
Hello all

I am getting the error: The maximum report processing jobs limit configured by your system administrator has been reached, using CRW XI R2.

Problem Description  

This error is occuring on a custom web reporting application previously running well in crystal 10 (Enterprise).  I have researched the problem to be my lack of calling a reportdoc.dispose on page_unload.  Here's my problem.  I am using asp.net 1.1, and I am using the crystal reportviewer.  Most reports are multi-page, so the users run the report and browse around it as needed.  To keep the report from re-running as they page through, I am caching the reportdocument to a session variable, and restoring it if the session variable is intact.  My problem is that if I do not call reportdocument.dispose in page_unload, I get the The maximum report processing jobs limit configured by your system administrator has been reached error.  If I call the dispose, when pagination occurs, I cannot rely upon my cached reportdocument, and I get another error (invalid object).  I think it’s pretty inefficient to re-run the report between every page, some take 15-20 seconds to process.  I also launch one of 12 different reports to separate popup windows for viewing, so it is important that each popup window retain it’s own state. Can you assist me with a strategy for doing this effectively?  BO samples that are distributed with the report tool do not dispose their reportdocuments at all.  

I have thought about pulling the dataset first, and caching that and pushing it at the report, but I would prefer not to rewrite the reports.  One BO tech came up with a solution where JS onclose launched a cleanup which was pretty ugly.  I am hoping that there are perhaps techniques for caching the report object that can make this work.  

Note that expanding the number of reports using the registry key is not a valid solution, without a dispose, the sessions are closing leaving the reportdocuments open.

Thanks!
0
Comment
Question by:DavidAvery
  • 6
  • 4
10 Comments
 
LVL 42

Accepted Solution

by:
frodoman earned 500 total points
ID: 17986721
Can you clarify something for me:  Are you hitting the limit as your users page through the reports or are you hitting it due to number of concurrent users?  In other words, if a single user is running the application and paging through a report will they hit this limit eventually or is the problem only because users don't log off so the threads stay active as new users come on?

My thinking at this point is that you could .dispose in your page_unload event, but only do it conditionally - don't dispose if the user is only paging.  This might entail catching the event from the crystal viewer when users page or perhaps hidding the crystal page buttons and placing your own on the form so you can check them for a click event to ignore the dispose.  

frodoman
0
 

Author Comment

by:DavidAvery
ID: 17987103
Thanks Frodoman.  

I am hitting the max 75 connections only because I am not disposing at all to keep the viewer live.  I guess the problem is that I believe that simply destroying the session object is not releasing the usage of the reportdocument.  Therefore as the sessions die, there is a handle to a reportdocument still live that is not being collected.  

My solution launches reports in popup windows which retain autonomy to page/rerun, etc.  I guess with your suggestion I would build in a JS onclose that could launch another page whose sole purpose was to unpack session, release the reportdocument, and kill the sessvar.

Do you know of a way to see usage?  This would certainly help test your theory.  There used to be a way to do it with CRW10.  Thank you!
0
 

Author Comment

by:DavidAvery
ID: 17987231
This is interesting:

http://msdn2.microsoft.com/en-us/library/ms225490(VS.80).aspx

Crystal Reports for Visual Studio 2005  
Use the Close() Method to free up the report  
Another way to optimize scalability in a Crystal Reports for Visual Studio 2005 project is to use one of the available Close() methods to release the memory that is used by the report.

Two Close() methods are available:

ReportDocument.Close() that is used with Crystal Reports.
ReportClientDocument.Close() that is used with unmanaged RAS or managed RAS.
The ReportDocument.Close() method

When using Crystal Reports for Visual Studio 2005, you can use the ReportDocument.Close() method to release the memory that the Crystal report consumes on the Web server.

How the ReportDocument.Close() method is accessed depends on whether the report is embedded or non-embedded:

If the report is embedded, a report wrapper class is generated to represent the report in code. This report wrapper class inherits from ReportDocument, and the Close() method is accessed by inheritance.
If the report is not embedded, it is loaded from the file directory into an instance of ReportDocument, and the Close() method is accessed directly from the ReportDocument class.
Note   For more information on embedded and non-embedded reports, see Should I Use Embedded or Non-embedded Reports?.
Both the Crystal report and the instance of the ReportDocument each consume memory. When the ReportDocument is freed from memory, the report continues to use memory.

For example, the ReportDocument instance falls out of scope when the Web page finishes loading. When the garbage collection for .NET disposes of the ReportDocument instance, the memory that is used by the ReportDocument instance is released from the Web server.

However, the report itself remains in memory on the Web server. It cannot be removed, because a ReportDocument instance no longer exists to access the report. When those circumstances are repeated in a highly scaled situation, the memory on the Web server fills with reports that are no longer being accessed.

To resolve that problem, call the ReportDocument.Close() method. The report itself is closed on the Web server and the memory is released for further reports.

When to call the ReportDocument.Close() method

The ReportDocument.Close() method should not be called on the page before the report has been displayed because, even if the report has been closed, ReportDocument will reopen the report if it is referenced again. The Close() method should only be called after the display process is complete.

The right time to call the Close() method is during the Page_Unload event.

The ReportClientDocument.Close() method

When using an unmanaged RAS or managed RAS server, reports are stored on the Report Application Server, but they are represented on the Web server by an instance of ReportClientDocument. If the ReportClientDocument instance passes out of scope without calling the ReportClientDocument.Close() method, the Report Application Server keeps the report open in memory, even though the report can no longer be accessed. When those circumstances are repeated in a highly scaled situation, the memory on the Report Application Server fills with reports that are no longer being accessed on the Web server.

To resolve that problem, call the ReportClientDocument.Close() method. The report is closed on the Report Application Server and the memory is released for further reports.

When to call the ReportClientDocument.Close() method

The Close() method should not be called on the page before the report has been displayed, because the report must remain open on the server until the display process has been completed.

For a ReportClientDocument instance, the Close() method immediately closes the report and the report cannot be reopened. Therefore, if the Close() method is called before the report is displayed, the report will be inaccessible and an exception will be thrown.

The right time to call the Close() method is during the Page_Unload event.

0
 
LVL 42

Expert Comment

by:frodoman
ID: 17987455
No, I don't know of a way to see usage - I suspect there is one but I've never gone looking for it.  I am certain that you are correct that destroying the session object does not dispose the reportdocument object - they are completely different objects.  You'll probably have better luck destroying the reportdocumentobject because that I believe is the one hanging on to your threads - the session is just data.

Honestly, what I typically do in my web applications is avoid all of the paging and caching issues completely.  My typical approach is to create the report and use the ExportToStream function to stream the results to the browser in PDF format.  My user base is comfortable navigating within a PDF, the Acrobat Reader has better search functionality than the Crystal viewer, and there are no threading or paging problems.  I do this routinely on all but the simplest reports.
0
 

Author Comment

by:DavidAvery
ID: 17987648
Yeah, I'm getting tired of fighting this battle.

Truly, I would like to be able to offer the user dashboard style reports for home pages with drill down and other functions, which is in all of the flash crystal adverts.  I also have a paid incident into BO right now.  It just bothers me that they tout interactive web reporting, and IMO, it just doesn't work.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 42

Expert Comment

by:frodoman
ID: 17987741
I've heard the same comments many times in this forum and I share those feelings...
0
 

Author Comment

by:DavidAvery
ID: 17996635
I'm going to try session_end.  I was thinking of using a ht of session keys, and looping through each, directcasting it to reportdocument and disposing.  Wish me luck!
0
 

Author Comment

by:DavidAvery
ID: 17996985
Looking good... testing found it running for all sessions, cast back to reportdocument worked :)  Doing a load test now.

    Sub Session_End(ByVal sender As Object, ByVal e As EventArgs)
        ' Fires when the session ends
        'kill off any reporting objects
        Dim ht As Hashtable
        Dim rdc As ReportDocument
        ht = Session("sessRpt")
        If Not ht Is Nothing Then
            For Each sKey As String In ht.Keys
                If Not Session(sKey) Is Nothing Then
                    rdc = CType(Session(sKey), ReportDocument)
                    rdc.Close()
                    rdc.dispose()
                End If
            Next
        End If

    End Sub
0
 

Author Comment

by:DavidAvery
ID: 17997915
Cool!!! it works!

I drop the report into session as standard with crystal, but also maintain a HT of sesskeys to unpack later.  I'm certain this can be improved on, but it works for me.  It's a shame that a paid call to CRW couldn't net a solution.

      Private Sub ConfigureCrystalReports()
        Dim sk As String = Request.QueryString("SK")
        If (Session(sk) Is Nothing) Then
            rdoc = New ReportDocument
            setupReport()
            Session(sk) = rdoc
            Dim HT As New Hashtable
            If Not Session("sessRpt") Is Nothing Then
                HT = CType(Session("sessRpt"), Hashtable)
            End If
            HT.Add(sk, System.DBNull.Value)
            Session("sessRpt") = HT
        Else
            rdoc = CType(Session(sk), ReportDocument)
        End If

        crv.ReportSource = rdoc
    End Sub


I have no dispose in my form_unload.  I set the number of printjobs down to 1 and ran reports using a bot until it gave me the error.  I waited a moment, and watched in debug mode as it unpacked and disposed all of the hanging reportdocuments.

Thanks frodoman for giving me some food for thought.
0
 
LVL 42

Expert Comment

by:frodoman
ID: 17997946
Sure thing - glad you've got it working!

frodoman
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Suggested Solutions

Hot fix for .Net Crystal Reports 10.2.3600.0 to fix problems with sub reports running on 64 bit operating systems ISSUE: Reports which contain subreports fail with error "Missing Parameter Value" DEPLOYMENT SERVER OS: Windows 2008 with 64 bi…
Hello everyone, Hope you find this as helpful as we did. We have on the company I work for an application built in Delphi V with Crystal Reports 8. We all know that Crystal & Delphi can be temperamental sometimes and the worst thing is, nearly…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now