最近,工作时,一些代码ASP.NET 项目的工作。我们需要一个跟踪工具采取的基本指标的用户活动(页面点击计数等等),我们会跟踪他们 Session, 然后保存数据的数据库通过 Session_EndGlobal.asax.

我开始远离黑客,初始代码的工作得很好、更新数据库的每一页上的负荷。我想除此数据库的打击对每一请求,虽然而仅仅依靠 Session_End 存储所有数据。

所有的追踪编码封装在 Tracker 类,包括性基本上包届会议变量。

的问题 是的,当我执行 Tracker.Log()Session_End 方法, HttpContext.Current.Session 在所跟踪的代码没有 NullReferenceException.现在,这是有道理的,因为 HttpContext 总是涉及 电流 请求时,以及当然在 Session_End, 是,没有请求。

我知道, Global.asax 有一个 Session 酒店其返回 HttpSessionState 这实际上似乎正常工作(I结束了注射它在跟踪)..

但我很好奇,怎么我可以得到相同的参考 HttpSessionState 所使用的对象 Global.asax外面Global.asax?

在此先感谢伙计们,我很欣赏你的投入。:)

有帮助吗?

解决方案

全球性的。asax实现HttpApplication-这是什么你说话的时候你打电话 从内。

MSDN文件 HttpApplication 已经详细说明如何可以得到保持它在HttpHandler例如,然后获得的各种性能。

然而

你的应用程序可以创建多个实例HttpApplication处理并行要求,这些实例可以被重新使用,所以只要拿起它以某种方式并不能提高你有权的一种。

我也还想补充一个值得注意的问题-如果你的应用程序的崩溃,有没有机制保障,session_end是要叫,你就已经失去了所有的数据在所有会议,显然不是一件好事。

我同意,登录在每一页上可能不是个好主意,但也许有一半的房子有一些异步记录发生的事情-你火的细节有一个记录类,每一个现在和以后的日志的细节你都后仍然不是100%固态如果应用程序崩溃,但你不太可能失去一切。

其他提示

回答的问题:

背景

每一个单页的请求转达一个新的 Session 目和膨胀然后将它从你届会议的商店。要做到这一点,它使用的饼干提供的客户或一种特殊的路径建造(为无cookie会话)。与本届会议的标识符,协商会议商店和反序列化(这也是为什么所有供应商,但InProc需要序列化)的新会议对象。

在这种情况下的InProc提供商,只手你参考它的存在 HttpCache 为键的本届会议的标识符。 这就是为什么InProc提供者降届会议时的状态 AppDomain 再循环(也为什么多的网络服务器不能分享InProc届会议的状态.

这一新建立的和膨胀的对象是卡在 Context.Items 收集,因此,它是可用于持续时间的请求。

你所做的任何更改的 Session 对象是那么坚持结束时请求该届会议商序列化的(或者的情况下InProc, HttpCache 项更新)。

由于 Session_End 火没有一个当前的请求在飞, Session 目的是纺成了ex-nilo,无信息可提供。如果使用InProc届会议的状态,期满 HttpCache 触发回调一个事件到你 Session_End 事件,使该会议项是可用的,但仍然是一个复制的什么是最后一个存在的 HttpContext.Cache.这个数值储存对 HttpApplication.Session 财产通过内部方法(称为 ProcessSpecialRequest)在那里随后提供。在所有其他情况下,内部来自 HttpContext.Current.Session 值。

你的答案

由于Session_End总是灾害空方面,应始终使用这一点。会议在这一事件,并通过HttpSessionState目下你的追踪编码。在所有其他情况下,这是完全没有取从 HttpContext.Current.Session 然后传递到的追踪编码。 不不, 然而,我们的追踪编码达到为本届会议的上下文。

我的回答

不要用 Session_End 除非你知道,本届会议的商店,你正在使用支持 Session_End, 它 如果返回 trueSetItemExpireCallback.只有在箱存储这不是 InProcSessionState 商店。它可以编写一届会议商店,但确实的问题,他们会处理的 Session_End 是那种模棱两可如果有多个服务器。

我认为你已经回答了自己的问题:通常的会议酒店在全球性的。asax和HttpContext.电流。会议都是相同的(如果有一个当前的请求)。但在的情况下一届会议时间超时,有没有活动的请求并因此你不能使用HttpContext.电流。

如果你想要访问的会议从方法称为通过Session_End,然后把它作为一个参数。创建一个重载版本的日志()方法,它需要一个HttpSessionState作为一个参数,那么呼叫跟踪。日志(这一点。会议)从Session_End事件的处理程序。

顺便说一句:你知道你可以不依赖于会议结束活动在任何情况下?它只会的工作,只要你有的话状态,在进程内。当使用SQL服务器或会话到管理会议的状态,本届会议结束活动将不火。

Session_End 事件提出的只有当 sessionstate mode 被设定为 InProcWeb.config 文件。如果届会的模式设置 StateServerSQLServer, ,该事件是没有提出。

使用 Session["SessionItemKey"] 得到会议的价值。

好吧,我在同样的问题,以跟踪该届会议的活动。而不是使用session_end事件,我已经实现IDisposable口和destructor我sessiontracker类。我已经修改Dispose()方法,以节省本届会议活动的数据库。我调用的方法obj。Dispose()当用户注销的点击按钮。如果用户关闭的浏览器中的错误,然后GC会呼析构,同时清洗的对象(不立即但肯定它会叫这种方法后的某个时候).析构方法的境内执行相同的处理()方法,以节省本届会议的活动进入数据库。

-山

会议是在你的全球性的。asax文件,在Session_Start事件。也许等到这一点做的东西?

记住,Session_End时运行的会议时间没有活动。浏览器不起源这一事件(因为它是无效),所以只有时间实际上,你会得到事件时使用InProc提供者。在每一个其他的提供者,这一事件永远不会着火。

道德的吗?不用Session_End.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top