0

Global.asax.cs ファイル (ASP.NET、C#、.NET Framework 4) の Session_Start メソッドでエラーが繰り返し発生します。エラーは次の行で発生しているようです

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

これは基本的に、この sessionId が SessionIds の現在のリストにあるかどうかを確認します。

エラーは

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)

エラーに対してログインしているユーザーはいません (これは、誰かがログインする前にスローされるためです)。しかし、ログインしようとしてエラーが報告されたユーザーはいません。これが表示される唯一の理由は、エラー ログに表示されているためです。

このエラーは数日間、1 分おきに発生し、数日間停止してから再表示されます。エラーごとにリモート ホストの IP を記録します。これは、私が確認したエラーのインスタンスごとに異なります。私は当初、これはある種の自動化されたジョブであると考えていましたが、場所の IP アドレスを追跡すると、ユーザーがいる場所、ユーザーがいない場所、およびプライベート (おそらく内部) IP アドレスから発信されていることがわかりました。 .

内部テストおよび QA システムでこのエラーを再現することはできません。私は 2 つの分野で助けを求めています。1 つ目は、これを引き起こしている可能性があることを誰かが知っていることです。2 つ目は、何が原因であるかを明らかにする情報をログに記録できますか?

ありがとう、ニール

編集

上記のエラー トレースのディクショナリは、SessionId と WebsiteVisitor クラスを格納するディクショナリです。

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

上記の ContainsKey if ステートメントを確認した後にのみ、これに追加します。発言全文は以下

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

1 に答える 1

1

Visitors辞書との同期に問題があるようです。ディクショナリコレクションはスレッドセーフではないため、読み取り/書き込みアクセスを制御する必要があります。この問題を解決するためにロックオブジェクトを使用しているようですが、そのアプローチの問題は、IISが各要求が同じAppDomainインスタンスまたは同じワーカープロセスで実行されることを保証しないことです。

クロススレッドロックの代わりに、クロスプロセスロックを確認する必要があります。Mutexを使用することをお勧めします。

アップデート

実際、@ RichardDeemingは非常に良い点を示しました。Visitorsオブジェクトは複数のプロセス/AppDomain間で共有されないため、その点で同期の問題になることはありませんが、辞書が何らかの形で破損しています。ConcurrentDictionaryの使用に切り替えて、フレームワークに同期を任せることをお勧めします。

一般に、Webアプリの静的プロパティは、複数のAppDomain間で共有できず、このような不思議な問題が発生する可能性があるため、お勧めできません。

于 2012-11-23T13:45:01.950 に答える