Asp.net Global.asax Session\u End未在启用sessonstate=ReadOnly的Session.放弃()上激发

Asp.net Global.asax Session\u End未在启用sessonstate=ReadOnly的Session.放弃()上激发,asp.net,session,Asp.net,Session,在我的ASP.Net会话通过会话.放弃()终止后,我正试图通过全局.asax.Session\u End()执行清理任务 我保证了以下几点 会话状态模式为InProc 我将数据写入SessionDataStore (会话[“foo”]=“bar”) 会话创建和.about()在不同的请求中执行,会话将被持久化 现在我正在经历以下行为: 当我使会话全局可写时(web.config中的enableSessionState=true),我的Global.asax.session\u End()会在

在我的ASP.Net会话通过
会话.放弃()
终止后,我正试图通过
全局.asax.Session\u End()
执行清理任务

我保证了以下几点

  • 会话状态模式为InProc
  • 我将数据写入SessionDataStore (
    会话[“foo”]=“bar”
  • 会话创建和.about()在不同的请求中执行,会话将被持久化
现在我正在经历以下行为: 当我使会话全局可写时(web.config中的
enableSessionState=true
),我的
Global.asax.session\u End()
会在
session.放弃()
后不久按预期触发

但是,当我在web.config中设置
enableSessionState=ReadOnly
,并且只允许某些页面通过
enableSessionState=“true
”向会话添加数据时,例如

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Login.aspx.cs" Inherits="WebPages_Login" EnableSessionState="true"%> 

Global.asax.Session\u End()
Session.about()之后不会触发,但只有在会话超时之后才会触发


如何使用全局设置的
enableSessionState=ReadOnly
Session.放弃()
上触发
Global.asax.Session\u End()

当从EnableSessionState=ReadOnly的页面触发Session.about()时,InProcSessionState不会标记为锁定(_locked=false)

仅当触发会话的请求的EnableSessionState=true时才会发生这种情况。放弃()

从System.Web.SessionState.InProcSessionStateStore.DoGet(…):

System.Web.SessionState.SessionStateModule.OnReleaseState()为放弃的会话激发_store.RemoveItem()。但是,只有当前InProcSessionState被锁定时,才会执行此RemoveItem()。请参阅InProcSessionStateStore.RemoveItem():

因此,在这种情况下(EnableSessionState=ReadOnly)Session.adward()不会放弃会话。在我看来,它就像一个ASP.Net bug

因此,我必须做的是触发清理代码两次:

  • 直接调用System.About()的位置
  • 在Global.asax.Session_End()中,用于超时会话

我的设置与OP类似。我的应用程序中的某些处理程序使用只读会话状态。但是,我发现.NET中的事件名称已明显更改()。在执行会话启动和会话结束后,我的会话将正确终止并调用会话结束。我不会在会话状态中存储任何项目。因此我认为这是不必要的

if (exclusive) {
                lockedByOther = true;

                // If unlocked, use a spinlock to test and lock the state.
                if (!state._locked) {
                    state._spinLock.AcquireWriterLock();
                    try {
                        if (!state._locked) {
                            lockedByOther = false;
                            state._locked = true;
                            state._utcLockDate = DateTime.UtcNow;
                            state._lockCookie++;
                        }
                        lockId = state._lockCookie;
                    }
                    finally {
                        state._spinLock.ReleaseWriterLock();
                    }
                }
            try {
            /* Only remove the item if we are the owner */
            if (!state._locked || state._lockCookie != lockCookie)
                return;

            /* prevent overwriting when we drop the lock */
            state._lockCookie = 0;
        }