문제

최근에 직장에서 ASP.NET 프로젝트를위한 일부 코드를 작업하면서 사용자 활동 (페이지 적중 수 등)에 대한 기본 메트릭을 취하기 위해 추적 UTIL이 필요했습니다. Session, 그런 다음 데이터를 DB에 저장하십시오 Session_End 안에 Global.asax.

해킹을 시작했고 초기 코드가 잘 작동하여 각 페이지로드에서 DB를 업데이트했습니다. 그래도 각 요청 에서이 DB 히트를 제거하고 원했습니다. Session_End 모든 데이터를 저장합니다.

모든 추적 코드는 Tracker 세션 변수를 본질적으로 래핑하는 속성을 포함하여 클래스.

문제 내가 실행했을 때입니다 Tracker.Log() 에서 Session_End 방법, HttpContext.Current.Session 추적기 코드에서 a NullReferenceException. 이제 이것은 이후에 의미가 있습니다 HttpContext 항상 현재의 요청, 물론 Session_End, 요청이 없습니다.

나는 그것을 알고있다 Global.asax a Session 반환하는 속성 a HttpSessionState 그것은 실제로 잘 작동하는 것 같습니다 (나는 그것을 추적기에 주입하게되었습니다) .. ..

하지만 나는 궁금합니다. HttpSessionState 사용한 객체 Global.asax ~에서 밖의Global.asax?

미리 감사드립니다. 입력에 감사드립니다. :)

도움이 되었습니까?

해결책

Global.asax는 httpapplication- 전화 할 때 말하는 것입니다. 이것 그 안에.

MSDN 문서 httpapplication 예를 들어 httphandler에서 그것을 잡을 수있는 방법에 대한 세부 정보가 있습니다. 그런 다음 다양한 속성에 액세스 할 수 있습니다.

하지만

응용 프로그램은 병렬 요청을 처리하기 위해 여러 개의 HTTPapplication 인스턴스를 생성 할 수 있으며 이러한 인스턴스를 재사용 할 수 있으므로 어떻게 든 올바른 것을 보증하지 않을 것입니다.

나도주의 사항을 추가 할 것입니다. 응용 프로그램 충돌이 발생하면 Session_end가 호출 될 것이라는 보증이 없으며 모든 세션에서 모든 데이터를 잃어 버릴 것입니다.

나는 모든 페이지에 로그인하는 것이 좋은 아이디어는 아니지만 아마도 비동기 로깅이 발생하는 중간 집이 아마도 로깅 클래스에 세부 정보를 발사하고, 지금은 매번 당신이 후에 세부 사항을 기록합니다 - 여전히 100%가 아닙니다. 앱이 충돌하면 견고하지만 모든 것을 잃을 가능성이 적습니다.

다른 팁

원래 질문에 더 잘 대답하려면 :

배경

모든 단일 페이지 요청이 새로운 것을 돌립니다 Session 객체를 한 다음 세션 상점에서 팽창시킵니다. 이를 위해 클라이언트가 제공 한 쿠키 또는 특수 경로 구조 (Cookieless 세션의 경우)를 사용합니다. 이 세션 식별자를 사용하면 세션 저장소와 상담하고 사형화 (모든 공급자이지만 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는 항상 Null 컨텍스트에 대해 발사되므로 항상 this.session을 사용하고 HttpsessionState 객체를 추적 코드로 전달해야합니다. 다른 모든 상황에서 HttpContext.Current.Session 그런 다음 추적 코드로 전달하십시오. 하지 마라, 그러나 추적 코드가 세션 컨텍스트에 도달하도록하십시오.

내 대답

사용하지 마십시오 Session_End 귀하가 지원하는 세션 스토어를 알지 않는 한 Session_End, 그거 하다 그것이 돌아 오면 true ~에서 SetItemExpireCallback. 유일한 상자 상점은 다음과 같습니다 InProcSessionState 가게. 누가 처리 할 것인지에 대한 질문은 세션 상점을 작성할 수 있습니다. Session_End 여러 서버가 있으면 모호합니다.

나는 당신이 이미 당신의 질문에 대답했다고 생각합니다. 일반적으로 Global.asax 및 httpcontext.current.session의 세션 속성은 동일합니다 (현재 요청이있는 경우). 그러나 세션 타임 아웃의 경우 활성 요청이 없으므로 httpcontext.current를 사용할 수 없습니다.

session_end by session_end가 호출 된 메소드에서 세션에 액세스하려면 매개 변수로 전달하십시오. 오버로드 된 버전을 만들어 httpsessionState를 매개 변수로 가져간 다음 Session_end 이벤트 핸들러에서 호출 트래커 (this.session)를 호출하십시오.

BTW : 어떤 경우에도 세션 엔드 이벤트에 의존 할 수 없다는 것을 알고 있습니까? 세션 상태 내 프로세스가있는 한만 작동합니다. SQL Server 또는 Stateserver를 사용하여 세션 상태를 관리 할 때 세션 종료 이벤트가 시작되지 않습니다.

그만큼 Session_End 이벤트는 일 때만 제기됩니다 sessionstate mode 설정되었습니다 InProc 에서 Web.config 파일. 세션 모드가 설정된 경우 StateServer 또는 SQLServer, 이벤트는 제기되지 않습니다.

사용 Session["SessionItemKey"] 세션 값을 얻으려면.

좋아, 나는 세션 활동을 추적하기 위해 같은 문제에있다. Session_end 이벤트를 사용하는 대신 SessionTracker 클래스에 idisposable 인터페이스와 파괴자를 구현했습니다. 세션 활동을 DB에 저장하기 위해 dispose () 메소드를 수정했습니다. 사용자가 로그 아웃 버튼을 클릭하면 메소드 obj.dispose ()를 호출했습니다. 사용자가 실수로 브라우저를 닫으면 GC는 객체를 청소하는 동안 파괴자를 호출합니다 (즉시는 아니지만 언젠가는이 방법을 호출 할 것입니다). 파괴자 방법은 내부적으로 동일한 처분 () 메소드를 실행하여 세션 활동을 DB로 저장합니다.

-shan

세션은 Session_Start 이벤트 중에 Global.asax 파일에서 사용할 수 있습니다. 이 시점까지 기다릴 때까지 기다릴까요?

Session_end는 세션이 활동없이 시간이지 나면 실행됩니다. 브라우저는 해당 이벤트를 시작하지 않으므로 (비활성이기 때문에) 실제로 이벤트를 얻는 유일한 시간은 Inproc 제공 업체를 사용할 때입니다. 다른 모든 공급 업체 에서이 이벤트는 결코 해고되지 않습니다.

도의적인? Session_end를 사용하지 마십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top