DNN性能优化方案系列(2)Page State Persistence

我在<< DNN性能优化方案系列(1)概述 >>说明DNN对性能优化做的努力,Page State Persistence的保存方法是其中一个措施之一.
下面来看下DNN4.5.5的实现.
先看 DotNetNuke_04.05.05_Source\Library\Components\Framework\PageBase.vb
#Region  "Protected Properties"

        
' '' -----------------------------------------------------------------------------
         ' '' <summary>
         ' '' PageStatePersister returns an instance of the class that will be used to persist the Page State
         ' '' </summary>
         ' '' <returns>A System.Web.UI.PageStatePersister</returns>
         ' '' <history>
         ' ''     [cnurse]        11/30/2005    Created
         ' '' </history>
         ' '' -----------------------------------------------------------------------------
         Protected   Overrides   ReadOnly   Property  PageStatePersister()  As  System.Web.UI.PageStatePersister
            
Get
                
' Set ViewState Persister to default (as defined in Base Class)
                 Dim  _persister  As  PageStatePersister  =   MyBase .PageStatePersister
                
If   Not  DotNetNuke.Common.Globals.HostSettings( " PageStatePersister " Is   Nothing   Then
                    
Select   Case   DirectCast (DotNetNuke.Common.Globals.HostSettings( " PageStatePersister " ),  String )
                        
Case   " M "
                            _persister 
=   New  CachePageStatePersister( Me )
                        
Case   " D "
                            _persister 
=   New  DiskPageStatePersister( Me )
                    
End   Select
                
End   If
                
Return  _persister
            
End   Get
        
End Property
#End Region

其中

Select   Case   DirectCast (DotNetNuke.Common.Globals.HostSettings( " PageStatePersister " ),  String )
         
Case   " M "     ' 选择将页面状态持久化保存于内存,M即memery首字母
                   _persister  =   New  CachePageStatePersister( Me )
         
Case   " D "    ' 选择将页面状态持久化保存于硬盘,D即Disk首字母,不过在主机设置里面似乎没有这个选项
                   _persister  =   New  DiskPageStatePersister( Me )
           
End   Select
CachePageStatePersister.vb
None.gif Imports  System.Text
None.gif
ExpandedBlockStart.gifContractedBlock.gif
Namespace DotNetNuke Namespace DotNetNuke.Framework
InBlock.gif
InBlock.gif    
''' -----------------------------------------------------------------------------
InBlock.gif
    ''' Namespace:  DotNetNuke.Framework
InBlock.gif
    ''' Project:    DotNetNuke
InBlock.gif
    ''' Class:      CachePageStatePersister
InBlock.gif
    ''' -----------------------------------------------------------------------------
InBlock.gif
    ''' <summary>
InBlock.gif
    ''' CachePageStatePersister provides a cache based page state peristence mechanism
InBlock.gif
    ''' </summary>
InBlock.gif
    ''' <history>
InBlock.gif
    '''        [cnurse]    11/30/2006    documented
InBlock.gif
    ''' </history>
InBlock.gif
    ''' -----------------------------------------------------------------------------
ExpandedSubBlockStart.gifContractedSubBlock.gif
    Public Class CachePageStatePersisterClass CachePageStatePersister
InBlock.gif        
Inherits PageStatePersister
InBlock.gif
InBlock.gif        
''' -----------------------------------------------------------------------------
InBlock.gif
        ''' <summary>
InBlock.gif
        ''' Creates the CachePageStatePersister
InBlock.gif
        ''' </summary>
InBlock.gif
        ''' <history>
InBlock.gif
        '''     [cnurse]        11/30/2006    Documented
InBlock.gif
        ''' </history>
InBlock.gif
        ''' -----------------------------------------------------------------------------
ExpandedSubBlockStart.gifContractedSubBlock.gif
        Public Sub New()Sub New(ByVal page As Page)
InBlock.gif            
MyBase.New(page)
ExpandedSubBlockEnd.gif        
End Sub

InBlock.gif
InBlock.gif        
''' -----------------------------------------------------------------------------
InBlock.gif
        ''' <summary>
InBlock.gif
        ''' Loads the Page State from the Cache
InBlock.gif
        ''' </summary>
InBlock.gif
        ''' <history>
InBlock.gif
        '''     [cnurse]        11/30/2006    Documented
InBlock.gif
        ''' </history>
InBlock.gif
        ''' -----------------------------------------------------------------------------
ExpandedSubBlockStart.gifContractedSubBlock.gif
        Public Overrides Sub Load()Sub Load()
InBlock.gif
InBlock.gif            
' Get the cache key from the web form data
InBlock.gif
            Dim key As String = TryCast(Page.Request.Params("__VIEWSTATE_CACHEKEY"), String)
InBlock.gif
InBlock.gif            
'Abort if cache key is not available or valid
InBlock.gif
            If String.IsNullOrEmpty(key) Or Not key.StartsWith("VS_"Then
InBlock.gif                
Throw New ApplicationException("Missing vaild __VIEWSTATE_CACHEKEY")
InBlock.gif            
End If
InBlock.gif
InBlock.gif            
Dim state As Pair = TryCast(DataCache.GetPersistentCacheItem(key, GetType(Pair)), Pair)
InBlock.gif
InBlock.gif            
If Not state Is Nothing Then
InBlock.gif                
'Set view state and control state
InBlock.gif
                ViewState = state.First
InBlock.gif                ControlState 
= state.Second
InBlock.gif            
End If
InBlock.gif
ExpandedSubBlockEnd.gif        
End Sub

InBlock.gif
InBlock.gif        
''' -----------------------------------------------------------------------------
InBlock.gif
        ''' <summary>
InBlock.gif
        ''' Saves the Page State to the Cache
InBlock.gif
        ''' </summary>
InBlock.gif
        ''' <history>
InBlock.gif
        '''     [cnurse]        11/30/2006    Documented
InBlock.gif
        ''' </history>
InBlock.gif
        ''' -----------------------------------------------------------------------------
ExpandedSubBlockStart.gifContractedSubBlock.gif
        Public Overrides Sub Save()Sub Save()
InBlock.gif
InBlock.gif            
'No processing needed if no states available
InBlock.gif
            If ViewState Is Nothing And ControlState Is Nothing Then
InBlock.gif                
Exit Sub
InBlock.gif            
End If
InBlock.gif
InBlock.gif            
Dim key As New StringBuilder()
InBlock.gif            
Dim _PortalSettings As PortalSettings = PortalController.GetCurrentPortalSettings()
InBlock.gif            
Dim TabId As Integer = _PortalSettings.ActiveTab.TabID
InBlock.gif
InBlock.gif            
'Generate a unique cache key
InBlock.gif
            With key
InBlock.gif                .Append(
"VS_")
InBlock.gif                .Append(
IIf(Page.Session Is Nothing, Guid.NewGuid().ToString(), Page.Session.SessionID))
InBlock.gif                .Append(
"_")
InBlock.gif                .Append(TabId)
InBlock.gif            
End With
InBlock.gif
InBlock.gif
InBlock.gif            
'Save view state and control state separately
InBlock.gif
            Dim state As New Pair(ViewState, ControlState)
InBlock.gif
InBlock.gif            
'Add view state and control state to cache
InBlock.gif
            DataCache.SetCache(key.ToString(), state, Nothing, DateTime.Now.AddMinutes(15), System.Web.Caching.Cache.NoSlidingExpiration, True)
InBlock.gif
InBlock.gif            
'Register hidden field to store cache key in
InBlock.gif
            Page.ClientScript.RegisterHiddenField("__VIEWSTATE_CACHEKEY", key.ToString())
InBlock.gif
ExpandedSubBlockEnd.gif        
End Sub

InBlock.gif
ExpandedSubBlockEnd.gif    
End Class

InBlock.gif
ExpandedBlockEnd.gif
End Namespace


继承PageStatePersister必须重载Load与Save
DNN将ViewState保存在内存,它将用于保存的Key保存的页面,用于从内存存取ViewState
Page.ClientScript.RegisterHiddenField("__VIEWSTATE_CACHEKEY", key.ToString())
生成一个隐藏域
<input type="hidden" name="__VIEWSTATE_CACHEKEY" id="__VIEWSTATE_CACHEKEY" value="VS_yjp0hlrgns3sqirbw0hsci45_36" />
此Key生成方法如下
With key
                .Append("VS_")
                .Append(IIf(Page.Session Is Nothing, Guid.NewGuid().ToString(), Page.Session.SessionID))
                .Append("_")
                .Append(TabId)
            End With

并设置Cache过期时间为15分钟
DataCache.SetCache(key.ToString(), state, Nothing, DateTime.Now.AddMinutes(15), System.Web.Caching.Cache.NoSlidingExpiration, True)
如果15分钟后页面才回传就会
Throw New ApplicationException("Missing vaild __VIEWSTATE_CACHEKEY")
就是这个页面的所有ViewState已经全部丢失.
这个Bug怎么处理,DNN不知有没有触觉的办法.我还没发现,或者目前根本还没解觉.
有好办法的同仁请提示下.

DiskPageStatePersister.vb

None.gif Imports  System.IO
None.gif
Imports  System.Text
None.gif
ExpandedBlockStart.gifContractedBlock.gif
Namespace DotNetNuke Namespace DotNetNuke.Framework
InBlock.gif
InBlock.gif    
''' -----------------------------------------------------------------------------
InBlock.gif
    ''' Namespace:  DotNetNuke.Framework
InBlock.gif
    ''' Project:    DotNetNuke
InBlock.gif
    ''' Class:      DiskPageStatePersister
InBlock.gif
    ''' -----------------------------------------------------------------------------
InBlock.gif
    ''' <summary>
InBlock.gif
    ''' DiskPageStatePersister provides a disk (stream) based page state peristence mechanism
InBlock.gif
    ''' </summary>
InBlock.gif
    ''' <history>
InBlock.gif
    '''        [cnurse]    11/30/2006    documented
InBlock.gif
    ''' </history>
InBlock.gif
    ''' -----------------------------------------------------------------------------
ExpandedSubBlockStart.gifContractedSubBlock.gif
    Public Class DiskPageStatePersisterClass DiskPageStatePersister
InBlock.gif        
Inherits PageStatePersister
InBlock.gif
InBlock.gif        
''' -----------------------------------------------------------------------------
InBlock.gif
        ''' <summary>
InBlock.gif
        ''' Creates the DiskPageStatePersister
InBlock.gif
        ''' </summary>
InBlock.gif
        ''' <history>
InBlock.gif
        '''     [cnurse]        11/30/2006    Documented
InBlock.gif
        ''' </history>
InBlock.gif
        ''' -----------------------------------------------------------------------------
ExpandedSubBlockStart.gifContractedSubBlock.gif
        Public Sub New()Sub New(ByVal page As Page)
InBlock.gif            
MyBase.New(page)
ExpandedSubBlockEnd.gif        
End Sub

InBlock.gif
InBlock.gif        
''' -----------------------------------------------------------------------------
InBlock.gif
        ''' <summary>
InBlock.gif
        ''' The CacheDirectory property is used to return the location of the "Cache"
InBlock.gif
        ''' Directory for the Portal
InBlock.gif
        ''' </summary>
InBlock.gif
        ''' <remarks>
InBlock.gif
        ''' </remarks>
InBlock.gif
        ''' <history>
InBlock.gif
        '''   [cnurse] 11/30/2006  Created
InBlock.gif
        ''' </history>
InBlock.gif
        ''' -----------------------------------------------------------------------------
ExpandedSubBlockStart.gifContractedSubBlock.gif
        Public ReadOnly Property CacheDirectory()Property CacheDirectory() As String
InBlock.gif            
Get
InBlock.gif                
Return PortalController.GetCurrentPortalSettings.HomeDirectoryMapPath & "Cache"
InBlock.gif            
End Get
ExpandedSubBlockEnd.gif        
End Property

InBlock.gif
InBlock.gif        
''' -----------------------------------------------------------------------------
InBlock.gif
        ''' <summary>
InBlock.gif
        ''' The StateFileName property is used to store the FileName for the State
InBlock.gif
        ''' </summary>
InBlock.gif
        ''' <remarks>
InBlock.gif
        ''' </remarks>
InBlock.gif
        ''' <history>
InBlock.gif
        '''   [cnurse] 11/30/2006  Created
InBlock.gif
        ''' </history>
InBlock.gif
        ''' -----------------------------------------------------------------------------
ExpandedSubBlockStart.gifContractedSubBlock.gif
        Public ReadOnly Property StateFileName()Property StateFileName() As String
InBlock.gif            
Get
InBlock.gif                
Dim key As New StringBuilder()
InBlock.gif                
With key
InBlock.gif                    .Append(
"VIEWSTATE_")
InBlock.gif                    .Append(Page.Session.SessionID)
InBlock.gif                    .Append(
"_")
InBlock.gif                    .Append(Page.Request.RawUrl)
InBlock.gif                
End With
InBlock.gif                
Return CacheDirectory & "\" & CleanFileName(key.ToString) & ".txt"
InBlock.gif            
End Get
ExpandedSubBlockEnd.gif        
End Property

InBlock.gif
InBlock.gif        
''' -----------------------------------------------------------------------------
InBlock.gif
        ''' <summary>
InBlock.gif
        ''' Loads the Page State from the Cache
InBlock.gif
        ''' </summary>
InBlock.gif
        ''' <history>
InBlock.gif
        '''     [cnurse]        11/30/2006    Documented
InBlock.gif
        ''' </history>
InBlock.gif
        ''' -----------------------------------------------------------------------------
ExpandedSubBlockStart.gifContractedSubBlock.gif
        Public Overrides Sub Load()Sub Load()
InBlock.gif
InBlock.gif            
Dim reader As StreamReader = Nothing
InBlock.gif
InBlock.gif            
' Read the state string, using the StateFormatter.
InBlock.gif
            Try
InBlock.gif                reader 
= New StreamReader(StateFileName)
InBlock.gif
InBlock.gif                
Dim serializedStatePair As String = reader.ReadToEnd
InBlock.gif
InBlock.gif                
Dim formatter As IStateFormatter = Me.StateFormatter
InBlock.gif
InBlock.gif                
' Deserialize returns the Pair object that is serialized in
InBlock.gif
                ' the Save method.      
InBlock.gif
                Dim statePair As Pair = CType(formatter.Deserialize(serializedStatePair), Pair)
InBlock.gif
InBlock.gif                ViewState 
= statePair.First
InBlock.gif                ControlState 
= statePair.Second
InBlock.gif            
Finally
InBlock.gif                
If Not reader Is Nothing Then
InBlock.gif                    reader.Close()
InBlock.gif                
End If
InBlock.gif            
End Try
InBlock.gif
ExpandedSubBlockEnd.gif        
End Sub

InBlock.gif
InBlock.gif
InBlock.gif        
''' -----------------------------------------------------------------------------
InBlock.gif
        ''' <summary>
InBlock.gif
        ''' Saves the Page State to the Cache
InBlock.gif
        ''' </summary>
InBlock.gif
        ''' <history>
InBlock.gif
        '''     [cnurse]        11/30/2006    Documented
InBlock.gif
        ''' </history>
InBlock.gif
        ''' -----------------------------------------------------------------------------
ExpandedSubBlockStart.gifContractedSubBlock.gif
        Public Overrides Sub Save()Sub Save()
InBlock.gif
InBlock.gif            
'No processing needed if no states available
InBlock.gif
            If ViewState Is Nothing And ControlState Is Nothing Then
InBlock.gif                
Exit Sub
InBlock.gif            
End If
InBlock.gif
InBlock.gif            
If Not (Page.Session Is NothingThen
InBlock.gif                
If Not Directory.Exists(CacheDirectory) Then
InBlock.gif                    Directory.CreateDirectory(CacheDirectory)
InBlock.gif                
End If
InBlock.gif
InBlock.gif                
' Write a state string, using the StateFormatter.
InBlock.gif
                Dim writer As New StreamWriter(StateFileName, False)
InBlock.gif
InBlock.gif                
Dim formatter As IStateFormatter = Me.StateFormatter
InBlock.gif
InBlock.gif                
Dim statePair As New Pair(ViewState, ControlState)
InBlock.gif
InBlock.gif                
Dim serializedState As String = formatter.Serialize(statePair)
InBlock.gif
InBlock.gif                writer.Write(serializedState)
InBlock.gif                writer.Close()
InBlock.gif            
End If
ExpandedSubBlockEnd.gif        
End Sub

ExpandedSubBlockEnd.gif    
End Class

InBlock.gif
ExpandedBlockEnd.gif
End Namespace

在源码中看到的保存于盘硬的,没有过期这回事,但总不能让那些没用的文件一直留着,要有个删除的办法.但DNN中似乎还没处理这个.
还有这个Key问题,

None.gif          ' '' -----------------------------------------------------------------------------
None.gif
         ' '' <summary>
None.gif
         ' '' The StateFileName property is used to store the FileName for the State
None.gif
         ' '' </summary>
None.gif
         ' '' <remarks>
None.gif
         ' '' </remarks>
None.gif
         ' '' <history>
None.gif
         ' ''   [cnurse] 11/30/2006  Created
None.gif
         ' '' </history>
None.gif
         ' '' -----------------------------------------------------------------------------
ExpandedBlockStart.gifContractedBlock.gif
         Public   ReadOnly   Property StateFileName() Property StateFileName() As String
InBlock.gif            
Get
InBlock.gif                
Dim key As New StringBuilder()
InBlock.gif                
With key
InBlock.gif                    .Append(
"VIEWSTATE_")
InBlock.gif                    .Append(Page.Session.SessionID)
InBlock.gif                    .Append(
"_")
InBlock.gif                    .Append(Page.Request.RawUrl)
InBlock.gif                
End With
InBlock.gif                
Return CacheDirectory & "\" & CleanFileName(key.ToString) & ".txt"
InBlock.gif            
End Get
ExpandedBlockEnd.gif        
End Property
与比CachePageStatePersister.vb不周到的地方是他似乎没考虑Page禁用Session的情况.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值