on 03-07-2016 10:03 PM
We have .net web application (Visual Studio 2013 - Web Forms - Crystal Report 13.0.16.1954 - NET Framework 3.5) in Windows Server 2008 R2 (x64) - IIS 7.5 and aleatorily application pool crash with the follow message:
A process serving application pool 'XXXXXXXXX' suffered a fatal communication error with the Windows Process Activation Service. The process id was 'DDDDDD'. The data field contains the error number.
After investigating found:
Exception Code: 0xC0000005
Exception Information: The thread tried to read from or write to a virtual address for which it does not have the appropriate access.
This problem occurs when application has many concurrent users at the same time.
¿My be crystal report memory leak error? ¿or bug in crystal reporte version 13.0.16.1954?
Please help me!!!!!
Thanks!!!
Check permissions on the folder, likely no access.
When Cr exports it first writes and empty file to the folder and then tries to delete it, if that fails it can throw an exception.
Don
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
From the info it suggests there is a share problem on the report object, typically that type of error is because you have too many reports still in session and not cleaning up the memory consumed processing the report.
Make sure you are using Sessions and PostBack method to clean up the reports when closing the page. Must close and dispose of the reports also.
You also must move your code from the Page_Load section to the Page_Init section.
Basic sample, uses RAS as a service so the code you use to open the report would be simpler:
private void Page_Init(Object sender, System.EventArgs e)
{
if (IsPostBack == false)
{
currentReport = new ReportClientDocument();
currentReport.ReportAppServer = "win-2k12-x64";
Object filepath = "rassdk://C:\\inetpub\\wwwroot\\Site for Don\\WebSite1\\rpt\\YourReport.rpt";
currentReport.Open(ref filepath, 1);
Session.Add("testReport", currentReport);
}
else
{
currentReport = (ReportClientDocument)Session["testReport"];
}
CrystalReportViewer1.ReportSource = currentReport;
// example - but be careful doing it this way, can cause problems
// should actually be done in the session code and/or page unload event.
currentReport = null;
}
protected override void OnUnload(EventArgs e)
{
}
// Provided the variables are still in scope ( declared globally or retrieved from session), then it should be cleaned up and disposed of properly
}
Don
This is the code of the page, it is in the Load event.
Although rptReporte.Close() and rptReporte.Dispose() are called at the end of the block Using, these calls are not in a try finally block for example, and rptReporte variable is not global.
Any suggestion of this block of code?
''''''''''''''''''''''''''''''''''''''CODE''''''''''''''''''''''''''''''''''''''
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim strTempo As String
Dim strFilename As String = ""
Dim strPie As String
Dim strDirectorioDestino As String
Dim strDirectorioOrigen As String
Dim strDirectorioRedireccion As String = ""
Dim objContextoSeguridad As DTOContextoSeguridad
Dim srvUtils As New srvUtiles
Try
objContextoSeguridad = CType(Session.Item("Seguridad"), DTOContextoSeguridad)
strDirectorioRedireccion = srvUtils.recuperarDirectorioRedireccionReportes(objContextoSeguridad.IDSistemaActual)
strDirectorioDestino = srvUtils.recuperarDirectorioDestinoReportes(objContextoSeguridad.IDSistemaActual)
strDirectorioOrigen = Server.MapPath("~/reportes")
If Not strDirectorioOrigen.EndsWith("\") Then
strDirectorioOrigen += "\"
End If
strPie = GenerarPie()
Using rptReporte As New CrystalDecisions.CrystalReports.Engine.ReportDocument
rptReporte.Load(strDirectorioOrigen & Request.QueryString("ReportFilename"))
Dim dtsRep As System.Data.DataSet
If Request.QueryString("DataSet") Is Nothing Then
dtsRep = CType(Session("dtsReporte"), System.Data.DataSet)
Else
dtsRep = CType(Session(Request.QueryString("DataSet").ToString), System.Data.DataSet)
End If
rptReporte.SetDataSource(dtsRep)
rptReporte.DataDefinition.FormulaFields.Item("rptPieDePagina").Text() = strPie
Dim strSeparadorFormulas As String
If Not Request.QueryString("SeparadorFormulas") Is Nothing Then
strSeparadorFormulas = Request.QueryString("SeparadorFormulas")
Else
strSeparadorFormulas = ","
End If
If Not Request.QueryString("Formulas") Is Nothing Then
For Each strTempo In Split(Request.QueryString("Formulas"), strSeparadorFormulas)
If Split(strTempo, "=")(0) = "FileImpresion" Then
strFilename = Split(strTempo, "=")(1)
Else
rptReporte.DataDefinition.FormulaFields.Item(Split(strTempo, "=")(0)).Text = "'" & Split(strTempo, "=")(1) & "'"
End If
Next
End If
If strFilename = "" Then
System.Threading.Thread.Sleep(1001)
strFilename = Format(Now(), "yyyyMMddhhmmss") & Session.SessionID & ".pdf"
End If
Dim formatType As Integer = ExportFormatType.PortableDocFormat
If Request.QueryString("TipoArchivo") IsNot Nothing AndAlso Request.QueryString("TipoArchivo") = "xls" Then
formatType = ExportFormatType.Excel
strFilename = strFilename.Replace(".pdf", ".xls")
End If
Try
If Not System.IO.Directory.Exists(strDirectorioDestino) Then
System.IO.Directory.CreateDirectory(strDirectorioDestino)
End If
Catch ex As Exception
PaginaHelper.Log(ex)
End Try
strDirectorioDestino = strDirectorioDestino & strFilename
Using _streamcrytal As System.IO.Stream = rptReporte.ExportToStream(formatType)
Using _streamfile As New FileStream(strDirectorioDestino, FileMode.Create)
Dim _bytes As Byte() = New Byte(_streamcrytal.Length) {}
_streamcrytal.Read(_bytes, 0, Convert.ToInt32(_streamcrytal.Length - 1))
_streamfile.Write(_bytes, 0, _bytes.Length)
_streamfile.Close()
_streamfile.Dispose()
End Using
_streamcrytal.Close()
_streamcrytal.Dispose()
End Using
rptReporte.Close()
rptReporte.Dispose()
End Using
Dim blnEliminaDstRPT As Boolean = True
If Request.QueryString("EliminarDtsRPT") IsNot Nothing AndAlso _
Not String.IsNullOrEmpty(Request.QueryString("EliminarDtsRPT")) Then
blnEliminaDstRPT = Request.QueryString("EliminarDtsRPT").ToString.Equals("S")
End If
If blnEliminaDstRPT Then
If Request.QueryString("DataSet") Is Nothing Then
Session.Remove("dtsReporte")
Else
Session.Remove(Request.QueryString("DataSet").ToString)
End If
End If
Catch ex As Exception
Logger.Log(ex)
Finally
Response.Redirect(strDirectorioRedireccion + strFilename)
End Try
End Sub
Code looks good, cleaning up the report and DS, I suggest moving it to the Page_Init section though. Standards show the Page Load even should not be used like this, we changed also.
It could be you are simply pushing the Engine, it's not designed to handle huge loads. It is not a Server Engine.
We do have RAS server service that can handle more reports and capable of adding more more Servers as needed.
How often do you get this error? Microsoft suggests cycling IIS often because Windows has no memory clean up to defrag it like UNIX OS's do, they can defrag on the fly so the app pool has contiguous memory space. Only way to clean up Windows memory is to re-boot.
Don
The error occurs every 10/20 minutes. Sometimes every 1 hour, is random.
I draw much attention because Crystal Report 2008 worked perfect for the same site and the same or more concurrency. Then he migrated to 2013 and began giving error.
I'll try to move the code to the Init event.
Thanks very much!!
Hello, maybe a silly question, but have you "Windows Process Activation Service" installed on your server (through Roles and Features wizard)?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Good day Cesar,
Thank you for posting to SCN as well as creating this inicdent.
Unfortunately CR for VS is an InProc version of RAS and is not designed to handle those kinds of loads. You can try adding GC.Collect to assist IIS and Windows to clean up and release memory but likely will not help.
CR requires Contiguous blocks of Memory and Windows is not capable of defragging memory on the fly. Only way to truly clean up memory is to reboot the server. Microsoft actually even highly recommends that you cycle IIS daily or more depending on the usage. You can create WEB farms to handle these.
I attached a link to a KBase article for the next version of RAS that runs as a Service. It's for OEM only but the same thing is available in CR Server which is a standalone PC capable running multiple RAS Servers in an unmanaged form, meaning it can load reports off the Hard drive. Or if published to CRS can load them from the CMS database. You can run CRS in a standalone mode so just RAS is running.
The next upgrade is to full BOE which then allows you to deploy multiple RAS server across multiple PC's to allow you to scale to your customers needs.
Bottom line is CR for VS was never designed to handle huge amounts of report processing. Nothing we can do about it or for you...
Your only option is to scale up to a RAS server running as a Service and to use multiple RAS servers as required.
Thank you
Don
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
70 | |
8 | |
8 | |
6 | |
6 | |
6 | |
6 | |
5 | |
5 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.