2012-11-23 1 views
0

Global.asax.cs 파일 (ASP.NET, C#, .NET Framework 4)의 Session_Start 메서드에서 반복적 인 오류가 발생합니다. 이 오류는 기본적으로이 sessionId가이 세션 id의 현재 목록에 있는지 확인합니다 다음 줄Session_Start 메서드에서 발생하는 반복 오류 추적

if (!OnlineVisitorsUtility.Visitors.ContainsKey(currentContext.Session.SessionID)) 

에서 발생하는 것으로 보인다.

오류가 (누군가가 로그인하기 전에이 발생되기 때문에) 오류에 로그인 한 사용자가없는

System.IndexOutOfRangeException: Index was outside the bounds of the array. 
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add) 
at TestSystem.WebSite.Global.Session_Start(Object sender, EventArgs e) Global.asax.cs:line 142 
at System.Web.SessionState.SessionStateModule.CompleteAcquireState() 
at System.Web.SessionState.SessionStateModule.BeginAcquireState(Object source, EventArgs e, AsyncCallback cb, Object extraData) 
at System.Web.HttpApplication.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() 
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) 

입니다. 그러나 사용자가 로그인을 시도하는 오류를보고 한 사람이 없습니다. 오류 로그에 나타나기 때문에 오류가 표시되는 유일한 이유입니다.

오류는 며칠 동안 매분마다 발생하고 다시 부상하기 전에 며칠 동안 멈 춥니 다. 각 오류에 대해 원격 호스트 IP를 기록하며, 내가 본 오류의 각 인스턴스마다 다릅니다. 나는 처음에는 이것이 일종의 자동화 된 작업이라고 생각했지만, 위치 IP 주소를 추적 할 때 우리는 사용자가있는 장소, 우리가하지 않는 장소 및 사적인 (내 생각에 내부적 인) IP 주소에서 발생한다는 것을 발견했습니다. .

내부 테스트 및 QA 시스템에서이 오류를 복제 할 수 없습니다. 나는 두 가지 영역에서 도움을 찾고 있는데, 첫째, 아무도이 문제를 일으킬 수있는 아이디어가 무엇인지, 둘째로, 그렇지 않다면 어떤 정보를 기록 할 수 있을까요?

감사합니다, 닐

편집

오류 추적의 사전은 위의 세션 ID와 WebsiteVisitor 클래스를 저장하는 사전이다.

public static Dictionary<string, WebsiteVisitor> Visitors = new Dictionary<string, WebsiteVisitor>(); 

우리는 위의 진술 경우 ContainsKey 확인 후 여기에 추가 할 수 있습니다. 당신이 당신의 Visitors 사전에 동기화 문제를 가지고있는 것처럼

lock (visitorsLock) 
{ 
    if (!OnlineVisitorsUtility.Visitors.ContainsKey(currentContext.Session.SessionID)) 
    { 
     OnlineVisitorsUtility.Visitors.Add(currentContext.Session.SessionID, new WebsiteVisitor(currentContext)); 
    } 
} 
+0

마치 'Session_Start' 어딘가에 삽입과 관련이있는 것처럼 보입니까? – James

+0

사전에 추가 할 때 발생합니다. 나는 아직도 어디에서인지 알 수 없다. 위의 편집을 참조하십시오. – Neil

+1

언제든지 해당 잠금 외부에서 사전에 액세스합니까? 내부 상태가 손상된 것처럼 들립니다. –

답변

1

가 소리 아래 전체 문입니다. Dictionary 컬렉션은 스레드로부터 안전하지 않으므로 읽기/쓰기 액세스를 제어해야합니다. 나는 당신이이 문제를 해결하기 위해 잠금 객체를 사용하는 것을 보지만, IIS가 각 요청이 동일한 AppDomain 인스턴스 또는 동일한 작업자 프로세스 하에서 실행되는 것을 보증하지는 않는다.

크로스 스레드 잠금 대신 교차 프로세스 잠금을 살펴볼 필요가 있으므로 Mutex을 사용하는 것이 좋습니다.

업데이트

사실 @RichardDeeming 아주 좋은 지적을했다 - 방문자가이 그러나, 그런 점에서 동기화 문제가되지 수 있도록 여러 프로세스/응용 프로그램 도메인간에 공유되지 않습니다 개체, 사전 어떻게 든가 손상되고 있습니다. ConcurrentDictionary을 사용하도록 전환하고 프레임 워크가 동기화를 처리하도록 권장합니다.

일반적으로 웹 응용 프로그램의 정적 속성은 여러 AppDomains에서 공유 할 수 없으며 이와 같은 신비한 문제로 이어질 수 있으므로 일반적으로 정적 속성은 좋지 않습니다.

+0

감사합니다. – Neil

+0

@James : 동일한 프로세스에서 여러 AppDomains간에 공유되는 정적 필드를 얻으려면 여러 농구를 뛰어 넘어야 할 것입니다. 그래서 다른 프로세스간에 공유되는 방식을 확신 할 수 없습니다. ? –

+0

@RichardDeeming 음,이 질문에 한 눈에 대답했지만, 당신은 아주 좋은 지적을했습니다 (나는 놓친 것 같습니다!). 나는 나의 대답을 업데이트 할 것이다. – James