Asp.net中水晶报表(Crystal Report )无法释放问题

现象:

近来在程序中使用了水晶报表——在一个页面中用水晶报表生成PDF文档。程序运行良好,但有一个很奇怪的问题:程序运行一段时间后就必须重起一下IIS。

分析过程:

我用Process Explorer对IIS进程检查发现进程里有很多文件没有释放。如下图:

 

IIS进程中充斥了很多临时文件没有释放。

 解决方法:

在用到水晶报表的页面事件Page_Unload中,将水晶报表相关对象释放。

 

 1Imports DataBean
 2Imports DataSet1
 3Imports System.Data
 4Imports CrystalDecisions.CrystalReports.Engine
 5Imports CrystalDecisions.Shared
 6
 7Partial Class _CrystallReportTesting
 8    Inherits System.Web.UI.Page
 9
10    Dim oRpt As New ReportDocument
11    Protected Sub Page_Load(ByVal sender As ObjectByVal e As System.EventArgs) Handles Me.Load
12        '' 水晶报表绑定
13        oRpt.Load(Server.MapPath("CrystalReport4.rpt"))
14        oRpt.SetDataSource(GetDataSourceFromOracle())
15        '' 设定水晶报表的ReportSource
16        CrystalReportViewer1.ReportSource = oRpt
17    End Sub

18    
19    Protected Sub Page_Unload(ByVal sender As ObjectByVal e As System.EventArgs) Handles Me.Unload
20        oRpt.Close()    ''释放水晶报表对象
21        oRpt.Dispose()
22        System.GC.Collect(0)
23    End Sub

24End Class

25

 

小插曲:

在调式过程中,我发现每当页面加载时执行Page_Load事件之后(如果没有其它代码),将会紧接着执行Page_Unload事件。这怎么回事?我直觉地以为Page_Unload会在客户端将网页关闭时触发。 

这也是我记录这个事件的主要原因:我总是不自然地将Web的编程模式理解为Windows编程模式。将http无状态性本质遗忘。主观臆断,不经思考地认为Page_Unload会在客户端将网页关闭时触发——这怎么可能呢?对于Asp.net执行模型来说,在IIS接到一个Get/Post请求时初始化一个与访问相关的页面类来处理该请求。并在处理完成后生成的HTML发送回客户端,之后该页面类等待被垃圾回收。

转一段网上的回帖,很好的回答了该问题:

It's confusing for windows developer. Remember about Unload event defenition. "Occurs when the server control is unloaded from memory" after each load or post back in server side all controls Unloaded from memory. Remember we talking about web application all controls get alived by request and died when response create and send to client.So thats why after load event Unload event called. 


posted @ 2009-11-05 14:51  Jerry Chou  阅读(823)  评论(1编辑  收藏  举报