2017-06-06 76 views
0

我收到一个不经常发生的错误,但客户端已经看到它并希望它修复。在什么情况下C#ASP.NET HttpContext.Current.Session抛出IndexOutOfRangeException?

基本上,它是一个IndexOutOfRangeException例外,但有什么奇怪的是,跟踪指向System.Web.HttpContext.Current。这怎么可能?

它未能上的线是这样的:


处 System.Collections.Specialized.NameObjectCollectionBase.BaseAdd(字符串名称 System.Collections.ArrayList.Add(对象的值) ,对象值) System.Web.SessionState.SessionStateItemCollection.set_Item(字符串 名称,对象的值)在 WebStateManager.set_Item(String键,对象的值) 在 \ WebStateManager.cs:线 53在UIStateManager.get_BookingParameters()在 WS \ App_Code文件\经理\ UIStateManager.cs:线
指数的 阵列的范围以外。

System.Web.HttpContext context = System.Web.HttpContext.Current; 

如果它是一个数组,我可以做计数等检查,但什么样的检查会比我一个try-catch在这里做其他的? enter link description here

public class Example 
{ 
    public static void Main() 
    { 
     int[] values1 = { 3, 6, 9, 12, 15, 18, 21 }; 
     int[] values2 = new int[6]; 

     // Assign last element of the array to the new array. 
     values2[values1.Length - 1] = values1[values1.Length - 1]; 
    } 
} 
// The example displays the following output: 
//  Unhandled Exception: 
//  System.IndexOutOfRangeException: 
//  Index was outside the bounds of the array. 
//  at Example.Main() 

我的项目代码

public override object this[string key] 
     { 
      get 
      { 
       if (Helpers.CommonFunctions.IsHttpSessionNull) 
       { return null; } 

       return HttpContext.Current.Session[key + Helpers.CommonFunctions.GetAppDomainMultiplexer()]; 
      } 
      set 
      { 
       if (Helpers.CommonFunctions.IsHttpSessionNull) 
       { return; } 

       if (value == null) 
       { 
        try 
        { 
         if (HttpContext.Current.Session[key + Helpers.CommonFunctions.GetAppDomainMultiplexer()] != null) 
         { 
          HttpContext.Current.Session.Remove(key + Helpers.CommonFunctions.GetAppDomainMultiplexer()); 
         } 
        } 
        catch 
        { 
        } 
       } 
       else 
       { 
         HttpContext.Current.Session[key + Helpers.CommonFunctions.GetAppDomainMultiplexer()] = value; 

       } 
      } 
     } 

故障堆栈跟踪如下;

0:072> !clrstack 
    OS Thread Id: 0x31ec (72) 
      Child SP    IP Call Site 
    000000aea766d968 000007f9736a4650 [HelperMethodFrame: 000000aea766d968] 
    000000aea766da50 000007f9674e0e5a System.Collections.ArrayList.Add(System.Object) 
    000000aea766da90 000007f966655292 System.Collections.Specialized.NameObjectCollectionBase.BaseAdd(System.String, System.Object) 
    000000aea766dae0 000007f9650ac4c9 System.Web.SessionState.SessionStateItemCollection.set_Item(System.String, System.Object) 
    000000aea766db20 000007f90ed89ce9 UTL.WebStateManager.set_Item(System.String, System.Object) 
    000000aea766dbf0 000007f90f29370c WebStateManagerHelper.get_OriginalPNR() 
    000000aea766dc80 000007f90f29242d QueryDynamicLoggingComponent.LogTransaction(System.String, System.String) 
    000000aea766e110 000007f90f2917e3 WSHelper.Log(System.String, System.String, Boolean, System.String) 
    000000aea766e160 000007f90f28fd17 WSHelper.GetResponse(System.String, SecurityInfo, System.String, System.String, System.String ByRef, System.String, System.String) 
    000000aea766e5d0 000007f90f29eae6 WSHelper.SendQuery(System.String, SecurityInfo, System.String) 
    000000aea766e7f0 000007f90f29e7f8 WSHelper.SendQuery(SecurityInfo, System.String) 
    000000aea766e840 000007f90f29e4af APIWSPool.SendAndReceiveQueryToString(Agency, System.String, Token, Boolean) 
    000000aea766e940 000007f90f29e374 APIWSPool.SendAndReceiveQuery(Agency, Token, Boolean) 
    000000aea766e9b0 000007f90f6168f4 FlightBookingManager.SearchFlightForMPSearchedFlightRecommendations1(Agency, FlightFareDrivenSearchInfo, Boolean) 
    000000aea766eb80 000007f90f615ec1 ApiFlightBookingProvider.SearchFlightForMPSearchedFlightRecommendations1(Agency, FlightFareDrivenSearchInfo, Boolean) 
    000000aea766ebe0 000007f90f6158f2 APICOM.Threading.OWCOutboundSearchThread.Work() 
    000000aea766edb0 000007f9674e2d45 System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) 
    000000aea766ef10 000007f9674e2ab9 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) 
    000000aea766ef40 000007f9674e2a97 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object) 
    000000aea766ef90 000007f9674fa161 System.Threading.ThreadHelper.ThreadStart() 
    000000aea766f2a8 000007f96e0eab53 [GCFrame: 000000aea766f2a8] 
    000000aea766f5f8 000007f96e0eab53 [DebuggerU2MCatchHandlerFrame: 000000aea766f5f8] 
    000000aea766f788 000007f96e0eab53 [ContextTransitionFrame: 000000aea766f788] 
    000000aea766f9a8 000007f96e0eab53 [DebuggerU2MCatchHandlerFrame: 000000aea766f9a8] 

回答

0

SessionStateItemCollection是不是线程安全的(见https://msdn.microsoft.com/en-us/library/system.web.sessionstate.sessionstateitemcollection(v=vs.110).aspx),你可能有多个线程写入/在同一时间从会话状态读数。

您需要找到访问HttpContext.Session或Page.Session的代码,并确保代码不在后台线程中运行。

https://msdn.microsoft.com/en-us/library/system.indexoutofrangeexception(v=vs.110).aspx - (搜索“违反线程安全”)

下面是一个使用锁,以尽量避免问题的一些示例代码。此代码非常快速和肮脏。我不推荐它。但很少重新设计你的系统,这可能是值得的。如果你使用这种技术,你必须把它放在的每个使用会话。

public override object this[string key] 
    { 
     get 
     { 
      if (Helpers.CommonFunctions.IsHttpSessionNull) 
      { return null; } 

      lock (HttpContext.Current.Session) 
      { 
       return HttpContext.Current.Session[key + Helpers.CommonFunctions.GetAppDomainMultiplexer()]; 
      } 
     } 
     set 
     { 
      if (Helpers.CommonFunctions.IsHttpSessionNull) 
      { return; } 

      lock (HttpContext.Current.Session) 
      { 
       if (value == null) 
       { 
        try 
        { 
         if (HttpContext.Current.Session[key + Helpers.CommonFunctions.GetAppDomainMultiplexer()] != null) 
         { 
          HttpContext.Current.Session.Remove(key + Helpers.CommonFunctions.GetAppDomainMultiplexer()); 
         } 
        } 
        catch 
        { 
        } 
       } 
       else 
       { 
        HttpContext.Current.Session[key + Helpers.CommonFunctions.GetAppDomainMultiplexer()] = value; 

       } 
      } 
     } 
+0

你有任何代码可以创建任务/线程/后台工作人员等吗? – mjwills

+0

你好mjwills, 我知道,这个对象仍然存在(会话状态)从我们的项目,但它已被删除的原生asp.net会话管理器(删除asp.net会话对象)。这个问题不能在本地/现场环境中重现。只发生在生产环境中。 – hodoor

+0

是什么让你认为这是事业@ONURDİKMEN?即使会话过期,你也不应该得到你所看到的例外。该异常的最常见原因是对Session对象的多线程访问。请参阅https://stackoverflow.com/questions/24987909/is-session-variable-thread-safe-within-a-parallel-for-loop-in-asp-net-page。 – mjwills

相关问题