Crystal Reports Exception: The maximum report processing jobs limit configured by your system administrator has been reached - crystal-reports

I'm facing a very buggy issue, in ASP.NET application after viewing the same report many times simultaneously I got this exception:
The maximum report processing jobs limit configured by your system
administrator has been reached.
Wait I know there are tons of solutions out there but all of them are not working with me.
I put ReportDocument.Close(); ReportDocument.Dispose(); in CrystalReportViewer_Unload event, and still throw the exception.
Private Sub CrystalReportViewer1_Unload(ByVal sender As Object, ByVal e As System.EventArgs) Handles CrystalReportViewer1.Unload
reportFile.Close()
reportFile.Dispose()
GC.Collect()
End Sub
I edit the PrintJobLimit registry in HKEY_LOCAL_MACHINE\SOFTWARE\SAP BusinessObjects\Crystal Reports for .NET Framework 4.0\Report Application Server\InprocServer and HKEY_LOCAL_MACHINE\SOFTWARE\SAP BusinessObjects\Crystal Reports for .NET Framework 4.0\Report Application Server\Server to -1 even to 9999, and still throw the exception.
Here is the code snippet where I call my report:
Table_Infos = New TableLogOnInfos()
Table_Info = New TableLogOnInfo()
Con_Info = New ConnectionInfo()
With Con_Info
.ServerName = ConfigurationManager.AppSettings("server_name")
.DatabaseName = ConfigurationManager.AppSettings("DB")
.UserID = user_name
.Password = pass_word
.Type = ConnectionInfoType.SQL
.IntegratedSecurity = False
End With
Table_Info.ConnectionInfo = Con_Info
If Session("recpt_lang") = "Arabic" Then
reportFile.Load(Server.MapPath("/Reports/") & "collectrecpt_new_ar.rpt")
ElseIf Session("recpt_lang") = "English" Then
reportFile.Load(Server.MapPath("/Reports/") & "collectrecpt_new.rpt")
End If
For Each mytable In reportFile.Database.Tables
mytable.ApplyLogOnInfo(Table_Info)
Next
CrystalReportViewer1.ReportSource = reportFile
CrystalReportViewer1.SelectionFormula = Session("SelectionForumla")
CrystalReportViewer1 = Nothing

You have to Dispose your report instance after all.
If you Dispose the report after showing it, you will never see the error "The maximum report processing jobs limit configured by your system administrator has been reached" again.
Dim report1 As rptBill = clsBill.GetReport(billNumber)
rpt.Print()
'Cleanup the report after that!
rpt.Close()
rpt.Dispose()

I would recommend moving your close/dispose/gc.collect code outside of that unload process. In other words:
Load report
Assign to Viewer Control
Show Report in Viewer Control
Close Viewer Control and Unload (completely)
Then close/dispose/gc.collect outside of any viewer control code
My guess is the viewer control is not completely closed when the report is being cleaned up.
Crystal is a very memory intensive process and very finicky.

Crystal Report document implements IDisposable interface. So all you have to do is to enclose the report's instance with using statement. It will be automatically closed and disposed once the using statement is completed. You can write something like that:
using(var report = GetInvoiceReport())
{
// your logic here
}
or (depends on your context):
using(var report = new ReportDocument())
{
// your logic here
}

Greetings I am too late to have answer on it,
all reply are working and i have seen but in case still you are facing same problem and error then please once go in to TEMP folder under "windows" directory and delete all instances of crystal report.
I am saying this because all above option will work but you are still in the maximum reach so first of all delete all instance then apply all the above suggestion.
thanks

Make sure you are using PUSH model to display your reports. Next you have to make one change in your Server's registry: Follow the path:
"HKEY_LOCAL_MACHINE\SOFTWARE\SAP BusinessObjects\Crystal Reports for .NET Framework 4.0\Report Application Server\InprocServer"
and you will see an item " PrintJobLimit" and you will see that its default value is 75. that means the server can only handle 75 reports at a time.
Dont worry about that and just modify the value to -1

Make sure IIS user have sufficient permission to delete files present in "c:/windows/temp" folder.
I face the same issue once I provide write permission to that folder then it solved my issue.Also make sure dispose that object after generating the file

I was working on local report server. I have hosted my web application in other pc. When I got such error I just did IISRESET and working fine now.
Try this, this could help you.

You have to Dispose your report instance after all. If you Dispose the report after showing it, you will never see the error:
The maximum report processing jobs limit configured by your system administrator has been reached
Code:
Dim report1 As rptBill = clsBill.GetReport(billNumber)
rpt.Print()
'Cleanup the report after that!
rpt.Close()
rpt.Dispose()

In my case, the report had 4 subreports...
What solved for me was changing the value of "PrintJobLimit", from 75 to 500, in the following Regedit paths:
\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\SAP BusinessObjects\Crystal Reports for .NET Framework 4.0\Report Application Server\InprocServer
\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\SAP BusinessObjects\Crystal Reports for .NET Framework 4.0\Report Application Server\Server

I know this thread is older, but if you configure the app pool setting "Recycling..." to recycle at, say, 180 minutes instead of 1740 minutes (the default), this might free up the needed resources.

Use These methods when unload the page
ReportDocument crystalReport;
protected void Page_Unload(object sender, EventArgs e)
{
if (crystalReport != null)
{
crystalReport.Close();
crystalReport.Dispose();
}
}
OR
protected void Page_Unload(object sender, EventArgs e)
{
if (crystalReport != null)
{
crystalReport.Close();
crystalReport.Clone();
crystalReport.Dispose();
crystalReport = null;
GC.Collect();
GC.WaitForPendingFinalizers();
}
}

I ended up using GC.WaitForPendingFinalizers in addition to the GC.Collect, close and dispose. I believe my web page was perhaps unloading and stopping thread processing prematurely before the garbage was properly processed (really?)
This is on Server 2012, SQL 2012, CR 13.0.2000.0
Here's my code:
#Region "Cleanup"
Private Sub crCleanup(Optional blnForce As Boolean = False)
Try
' Crystal(code Is Not managed, i.e.it) 's COM interop => you have to manually
' release any objects instantiated. Make sure you set the ref to nothing and
' also call the dispose method if it has one.
' under some conditions, we don't want to destroy the ReportDocument (e.g. report page-to-page navigation)
If blnForce OrElse Me.blnPageHasFatalError OrElse (Not Me.CrystalUseCache) Then ' do not release when using cache! (unless forced)
If Not crReportDocument Is Nothing Then Me.crReportDocument.Close()
If Not crReportDocument Is Nothing Then Me.crReportDocument.Dispose()
If Not thisWebAppUser Is Nothing Then Me.thisWebAppUser.Dispose()
Me.thisWebAppUser.ClearReportCache() ' we are using HttpContext.Current.Cache.Item instead of sessions to save CR document
End If
' the rest of the items, we'll always want to clean up
If Not crParameterFieldDefinitions Is Nothing Then crParameterFieldDefinitions.Dispose()
If Not crParameterFieldDefinition Is Nothing Then crParameterFieldDefinition.Dispose()
crParameterFields = Nothing
crParameterField = Nothing
crParameterFieldName = Nothing
crParameterValues = Nothing
crParameterDiscreteValue = Nothing
crParameterDefaultValue = Nothing
crParameterRangeValue = Nothing
'
If Not crSections Is Nothing Then crSections.Dispose()
If Not crSection Is Nothing Then crSection.Dispose()
If Not crReportObjects Is Nothing Then crReportObjects.Dispose()
If Not crReportObject Is Nothing Then crReportObject.Dispose()
If Not crSubreportObject Is Nothing Then crSubreportObject.Dispose()
If Not crDatabase Is Nothing Then crDatabase.Dispose()
If Not crTables Is Nothing Then crTables.Dispose()
If Not crTable Is Nothing Then crTable.Dispose()
crLogOnInfo = Nothing
crConnInfo = Nothing
crDiskFileDestinationOptions = Nothing
ConnParam = Nothing
If Not subRepDoc Is Nothing Then subRepDoc.Dispose()
Catch ex As Exception
Me.thisWebAppUser.SendSysAdminMessage("Failed CR cleanup", ex.ToString)
End Try
' yes, use of the GC.Collect (and even more the GC.WaitForPendingFinalizers) is highly controversial
'
' the reality is that rendering crystal reports is rather slow compared to most web operations
' so it is expected that waiting for GC will have relatively little performance impact
' and will in fact, help tremendously with memory management.
'
' try setting these values to 1 and confirm for yourself by instantiating multiple crDocuments in different browsers if you don't believe it:
'
' HKEY_LOCAL_MACHINE\SOFTWARE\SAP BusinessObjects\Crystal Reports for .NET Framework 4.0\Report Application Server\InprocServer
' HKEY_LOCAL_MACHINE\SOFTWARE\SAP BusinessObjects\Crystal Reports for .NET Framework 4.0\Report Application Server\Server
'
' or google this error: The maximum report processing jobs limit configured by your system administrator has been reached
'
' I believe the problem is that on very fast servers, the page unloads and stops processing code to properly cleanup the Crystal Report objects
'
' This is done in 3 places:
' Report Viewer (Page_Unload and CrystalReportViewer1_Unload) rendering a report will of course always using a processing job
' Report Parameter Selector (Page_Unload) loading a crDocument without rendering a report still counts towards CR processing job limit.
' Custom Control crReportParameterSelectionTable (Public Overrides Sub dispose())
GC.Collect()
GC.WaitForPendingFinalizers()
End Sub
'***********************************************************************************************************************************
'
'***********************************************************************************************************************************
Private Sub Page_Unload(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Unload
'If Me.IsCallback Then Exit Sub ' the menutree causes callbacks, but we are not interested
crCleanup()
' response object not available here, so cannot redirect (such as in the case of XLS opeing in a separate window)
' if for some crazy reason there is STILL a crReportDocument, set it to nothing
' If Not crReportDocument Is Nothing Then Me.crReportDocument = Nothing
' Me.CrystalReportViewer1 = Nothing
End Sub
Private Sub CrystalReportViewer1_Unload(ByVal sender As Object, ByVal e As System.EventArgs) Handles CrystalReportViewer1.Unload
'If Me.IsCallback Then Exit Sub ' the menutree causes callbacks, but we are not interested
crCleanup()
End Sub
End Region

Related

How can I get Excel to close when I'm done with it?

This is in a COM API Word AddIn. And yes normally Hans Passant's advice to let .NET clean everything up works.
But it is not working for the following case - and I have tested running normally (no debugger) and have narrowed it down to this specific code:
private Chart chart;
private bool displayAlerts;
private Application xlApp;
Chart chart = myShape.Chart;
ChartData chartData = chart.ChartData;
chartData.Activate();
WorkbookData = (Workbook)chartData.Workbook;
xlApp = WorkbookData.Application;
displayAlerts = xlApp.DisplayAlerts;
xlApp.Visible = false;
xlApp.DisplayAlerts = false;
WorksheetData = (Worksheet)WorkbookData.Worksheets[1];
WorksheetDataName = WorksheetData.Name;
WorksheetData.UsedRange.Clear();
// ... do a bunch of stuff including writing to the worksheet
xlApp.DisplayAlerts = displayAlerts;
WorkbookData.Close(true);
I think the problem is likely Word is giving me this workbook and so who knows what it is doing to instantiate Excel. But even after I exit Word, the Excel instance is still running.
Again, in Word (not Excel), accessing a chart object to update the data in the chart.
COM objects need to be released completely, else "orphaned" objects can keep an application in memory, even after the code that called it goes out-of-scope.
This particular case may be special (compared to other code you've used previously) due to using xlApp. By default, an Excel Application object is not needed or used when manipulating charts with the object model introduced in Office 2007 (I think it was). It's used in the code in the question in order to hide the Excel window, which is visible by default (and by design). But the object model isn't designed to handle cleaning that up - it assumes it isn't present...
In my tests, the object is released correctly when (referencing the code in the question):
All Excel objects are set to null in the reverse order they are instantiated, being sure to quit the Excel application before trying to set that object to null:
WorksheetData = null;
WorkbookData = null;
xlApp.Quit();
xlApp = null;
Then, C# has a tendency to create objects behind the scenes when COM dot-notation is used - these don't always get cleaned up (released) properly. So it's good practice to create an object for each level of the hierarchy being used. (Note: VBA doesn't have this problem, so any code picked up from a VBA example or the macro recorder needs to be re-worked in this respect.) From the code in the question this affects WorksheetData.UsedRange.Clear();
Excel.Range usedRng = WorksheetData.UsedRange;
usedRng.Clear();
usedRng = null;
And the standard clean up, to make sure everything is released at a predictable moment:
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
When things like this crop up, I always refer to ".NET Development for Office" by Andrew Whitechapel. That's really "bare bones" and some of it no longer relevant, given the changes to C# over the years (to make it "easier to use" in the way VB.NET is "easier"). But how COM interacts with .NET hasn't changed, deep down...

JBPM - Process instance XXX is disconnected

We are facing error 'Process instance XXX is disconnected' very frequently in our project and holding up the tasks operations.
We are using SynchronizedTaskService for task operation:
Code snippet are below:
final RuntimeManager runtimeManager = RuntimeEngineFacory.getRuntimeManager();
final RuntimeEngine engine = runtimeManager.getRuntimeEngine(EmptyContext.get());
SynchronizedTaskService taskService = (SynchronizedTaskService) engine.GetTaskService();
It was raised in one of JBPM bugzilla https://bugzilla.redhat.com/show_bug.cgi?id=1161574
Please help if anyone has any clue.
After lots of research and finding (including different community discussion) came to little close to this issue solution.
Below are the main reason of this:
Using the (runtime manager) Singleton strategy with JTA transactions
(UserTransaction or CMT) is not recommended because there is a race
condition when using this. This race condition can result in an
IllegalStateException with a message similar to "Process instance XXX
is disconnected."
If you are using Singleton Strategy then make sure you are Synchronizing your call to JBPM.
Solution
Better to use Per Process Runtime Strategy so that JBPM engine will make sure strict relationship between Process Instance and Session. Session will remain associated till entire lifetime of Process Instance. This will also assure that Session are not shared across. This is I think most advance strategy available in JBPM.
Finally I am able to resolved this issue.
For benefit of whoever facing issue:
- This issue appears whenever you have not properly managed transactions
There were some place we were managed transaction incorrectly and somehow JBPM internally InternalKnowledgeRuntime set to null.
By the way this errors throws from
class: ProcessInstanceImpl
method: getProcess()
public Process getProcess(){
if(this.process == null){
if(processXml == null){
if(kruntime == null){
throw new RuntimeException("Process instance " + id + "[" + processId + "] is disconnected. "));
}else{
other code ...........
}
}
}
}

Order of events reversed 'Ribbon_Load' and 'ThisAddin_Startup' Word VSTO Add-in. (Build 8201.2025 onwards)

As of Build 8201.2025 there has been an unexpected change to the order of events when loading a VSTO addin with a Ribbon in Word.
Using Office version 16.0.8067.2115 or older. When loading the addin the following order of events is observed (as has always been the case).
Ribbon_Load event
ThisAddin_Startup event
Using Office versions 8201.2025, 8201.2064 or 8201.2075 or newer the order of events is reversed which is an unexpected breaking change.
ThisAddin_Startup event
Ribbon_Load event
I have created a simple VSTO Addin using a Visual Designer Ribbon to demonstrate the issue.
>
Public Class Ribbon1
Private Sub Ribbon1_Load(ByVal sender As System.Object, ByVal e As RibbonUIEventArgs) Handles MyBase.Load
System.Diagnostics.Debug.Write("Ribbon1_Load event called.")
'Pass the Ribbon to the Addin.
ThisAddIn.MyRibbon = Me
End Sub
End Class
Public Class ThisAddIn
Public Shared Property MyRibbon As Ribbon1 = Nothing
Private Sub ThisAddIn_Startup() Handles Me.Startup
Debug.Write("ThisAddin_Startup Called")
If (MyRibbon Is Nothing) Then
Debug.Write("MyRibbon is nothing - the ribbon was not captured.")
Else
Debug.Write("Ribbon captured successfully.")
End If
End Sub
End Class
Debug output for 16.0.8067.2115 32 bit
[7772] Ribbon1_Load event called.
[7772] ThisAddin_Startup Called
[7772] Ribbon captured successfully.
Debug output for 16.0.8201.2075 32 bit
[13556] ThisAddin_Startup Called
[13556] MyRibbon is nothing - the ribbon was not captured.
[13556] Ribbon1_Load event called
I have posted this up on the Microsoft Support forums however they have stopped responding and since released this version to the Current office channel I need help from the dev community.
Has anyone found a successful workaround? This change of timing is causing alot of problems with how we initialise. It would be ideal for Microsoft Support to provide a solution or workaround until they investigate this bug.
I always got Ribbon_Load before ThisAddin_Startup because I use Ribbon XML. Ribbon UI allow less controls ... As the both are "entry" points, I suggest you to use only Ribbon1_Load at startup. Or, if you use the Ribbon XML model and you want the very very first entry point, try its constructor
I am not feeling that issue as a bug, to make Word fast many processes are asynchronous. So, in my opinion, the first of ThisAddin_Startup or Ribbon1_Load to start can accidentally change depending on many factors: System performances, Word started alone, Word started via a doc ...
Hope this helps someone! We used the following workaround successfully to work around the changed office load behavior.
Within ThisAddIn_Startup loop until the Ribbon load event has fired and the ribbon is captured.
While m_oRibbon Is Nothing
If (timeWaited >= MAX_WAIT_TIME) Then
Exit Try
End If
Threading.Thread.Sleep(50)
timeWaited = timeWaited + 50
End While

Some beginner questions

I guess I'll start by saying I am very new to B4A, and to programming in general. I have some very basic java and html exp. but that's it. I do not have any basic4ppc or really any IDE experience. Been using B4A for a few days now and can't get over the hump. Here are my noob questions:
Does having many activities (20-30+) slow down the app? Is there a downside to having a lot of activities?
I can't figure out how to scroll in the designer. I am trying to make a screen that has 25 buttons down in 1 column. However I can't scroll down to add more buttons below. I am able to add buttons programmically and in the fashion that I want (using a for loop), but is it normal to create views at runtime like this?
How do you ensure your app looks the same across all devices? Tablets? I have a scroll view that fits perfect in the emulator, but on my phone (droid x), the bottom of the scroll view is not stretched to the bottom of the phone. I use the code: scvScreen1.Initialize(100%y). Is that not right?
I have a Email screen in which is comprised of an edittext and a Send button, so that the users can send me questions from the app. However the Send button gives me this error on the 'URI =' line: "LastException java.lang.NumberFormatException: mailto:" here is the code:
Sub btnSendEmail_Click
Dim Uri As String
Uri="mailto:me#gmail.com?subject=Test Email&body=" + edtHelpEmail.Text
Dim Intent1 As Intent
Intent1.Initialize(Intent1.ACTION_VIEW,Uri
StartActivity(Intent1)
End Sub
Or is there another way to open the device's default email program?
Regarding last question, how do I copy error messages to clipboard?? I selected the red error message on the bottom right of the IDE and tried ctrl-c, but didn't work.
In B4A, what is a good method of storing persistent data? All I really need to store are some strings. Nothing fancy. These strings are to be stored locally. AI made this easy by using TinyDB.
When using the designer, how do you ensure your views are centered on all devices? For instance, I have a screen that has several rows made up of: (label, edittext, label). And I want each row to be center aligned. Do I do this programmically? I'm thinking I would have to append each row of (label, edittext, label) to a panel, then in the code center the panel. Is this correct?
That's all I got for now, but I'm sure there will be plenty more questions later.
1) The whole idea of android is to small components i.e. Apps working together, so no need to worry about opening lots of activities. Memory is very well managed behind the scenes in Android.
2) Sure. That sounds fine to me. Use the Layout designer as much as you can and then add the dynamic stuff later. It's all about striking a balance between the size of your code and the number of activities.
3) In the Designer there's an option called 'Send to UI Cloud'. This compares your app over multiple screen sizes. You can also scale your design and programmatically resize specific controls within your app in the Activity_Create Lifecycle
4) What you're doing is almost correct. I corrected your code:
Sub MailTo(StrAddress As String, StrSubject As String, StrBody As String)
Dim StrMethod As String = "Sub MailTo(StrAddress As String, StrSubject As String, StrBody As String)"
Try
Dim StrUri As String
StrUri = "mailto:" & StrAddress & "?subject=" & StrSubject & "&body=" & StrBody
Dim Intent As Intent
Intent.Initialize(Intent.ACTION_VIEW, StrUri)
StartActivity(Intent)
Catch
If BlnLoudExceptions Then CdException.Show(StrClass, StrMethod, LastException)
End Try
End Sub
I tend to have a code module called CdIntent.bas for these functions as it both keeps the project organised and makes it easier to implement the same functionality across projects.
Then to call you would use
CdIntent.MailTo("me#yes.no", "Subject!", "Body!")
5) I have a file called CdException.bas
Sub Process_Globals
'These global variables will be declared once when the application starts.
'These variables can be accessed from all modules.
End Sub
Sub Show(StrClass As String, StrMethod As String, Ex As Exception)
LogColor("Exception: " & Ex.Message & " - Class: " & StrClass & " - Method: " & StrMethod, Colors.Magenta)
End Sub
and then wrap functions in the following way:
Sub FunctionName(...Parameters...) as Int
Dim StrMethod As String = "Sub Sleep(LngMilliseconds As Long)"
Dim IntResult As Int = 0
Try
[code here inc. IntResult = ???]
Catch
If BlnLoudExceptions Then CdException.Show(StrClass, StrMethod, LastException)
End Try
Return IntResult
End Sub
BlnLoudExceptions is a global boolean that you'd declare in
Process_Globals that you can switch on an off exception logs.
StrClass is a global String that you'd declare in Process_Globals
that contains the name of the class e.g. "CdIntent.bas"
The exceptions then appear in magenta in the log screen along with the method name and class in which they occurred allowing you to home in on them.
6) I have a table in an SQLLite database called TabletSettings, which has two TEXT colums called 'Name' and 'Value'. It works well and gets you into a (what I think is a) good habit of always having a database available to your app from the get-go.
7) I'll get back to you on this as I haven't done this before.
Until then, the following thread will help you in the B4A forum http://www.basic4ppc.com/android/forum/threads/convert-integer-to-dip.18800/
I agree with Jim's point but will attempt to answer 1.
I'm new to android myself but as I understand it activities on the whole are only running when active. Unless you are using the app to continuously do something there is only one activity at a time. The number of activities is likely to affect the ram available more than anything. Lastly it might be worth walking first rather than running so to speak but trying a single and then add multiple activities.
You could try adding a ListView or ScrollView where the items are the buttons, this seems to be the std way of doing things otherwise a tabbed view.

Datareader speed problem in vs.2008

I have 20 different methods and use datareader to read and get result from these functions in the same event.In top of page I create datareader and then begin to load it step by step(It uses same connection and same data access function).Till 15.function datareader loads without problem but after 15,it loads slowly(record count is about 20-30).When i close datareader after 15.function,this problem doesnt occur.But now after 15.function,i should close datareader if i execute some function.Why does this problem occur,I dont know.I posted sample code here.
'Trying method 1
strSQL.ToString="Select * from A"
dr = DB_Gateway.ReadAndBind(strSQL.ToString)
'Trying method 2
strSQL.ToString="Select * from B"
dr = DB_Gateway.ReadAndBind(strSQL.ToString)
'Trying method 15
strSQL.ToString="Select * from K"
dr = DB_Gateway.ReadAndBind(strSQL.ToString)
AFTER 15. EXECUTION,DATAREADER BEGINS TO LOAD DATA SLOWLY.WHEN I ADD DR.CLOSE AND EXECUTE IT,I DONT HAVE PROBLEM.IF I DONT DO IT,IT LOADS 20 RECORDS WITHING 5 SECONDS.THIS IS MY READANDBIND FUNCTION.I AM CONNECTING ORACLE 11 G.WHAT CAN CAUSE THIS PROBLEM?
Public Shared Function ReadAndBind(ByVal SQL As String) As OracleDataReader
Dim oraCommand As New OracleCommand
With oraCommand
.Connection =
New OracleConnection(CONN_NAME)
.CommandText = SQL
Dim dtreader As OracleDataReader
Try
.Connection.Open()
dtreader = .ExecuteReader(CommandBehavior.CloseConnection)
Catch ex As Exception
Exception_Save(ex.Message, oraCommand.ToString)
Throw
Finally
'.Connection.Close()
'.Connection.Dispose()
oraCommand.Dispose()
oraCommand =
Nothing
End Try
Return dtreader
End With
End Function
No, you are not using the same connection for all the commands, you are opening a new connection for each one. As you fail to close them, at the end of the code you will be having 20 database connections open at once.
Also, you are not using a single data reader, you are creating a new data reader for each query. When you assign the method result to the dr variable it's not reusing the data reader, it's throwing away the reference to one reader and replaces it with a new one. It's normal to use one reader for each result, but it means that you have to close each data reader before getting the next, or you will get an unreachable object that holds on to a database connection until the garbage collector removes it.
If you close each reader before getting the next, the database connection will be closed and returned to the connection pool so that it can be reused for the next query. Slightly better would be to create a single connection object for the page and use that for each command, that will save a few round trips to the database.