【问题标题】:Under what circumstance C# ASP.NET HttpContext.Current.Session throws, IndexOutOfRangeException?在什么情况下C# ASP.NET HttpContext.Current.Session 抛出IndexOutOfRangeException?
【发布时间】:2017-06-06 12:46:16
【问题描述】:

我收到一个不常发生的错误,但客户已经看到并希望修复它。

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

它失败的那一行是这样的:


在 System.Collections.ArrayList.Add(对象值)在 System.Collections.Specialized.NameObjectCollectionBase.BaseAdd(字符串 名称,对象值)在 System.Web.SessionState.SessionStateItemCollection.set_Item(字符串 名称,对象值)在 WebStateManager.set_Item(字符串键,对象值) 在 \WebStateManager.cs:行 53 在 UIStateManager.get_BookingParameters() 中 WS\App_Code\Managers\UIStateManager.cs:line 2746
索引超出范围 数组。

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] 

【问题讨论】:

    标签: c# asp.net web-services session indexoutofrangeexception


    【解决方案1】:

    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 - (搜索“违反线程安全”)

    下面是一些使用锁定来尝试避免问题的示例代码。这段代码非常快速和肮脏。我不推荐它。但是,如果不重新构建您的系统,这可能是值得的。如果你使用这种技术,你必须在每次使用 Session 时使用它。

        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;
    
                    }
                }
            }
    

    【讨论】:

    • 你有创建任务/线程/后台工作者等的代码吗?
    • 你好 mjwills,我知道,这个对象在我们的项目中仍然存在(会话状态),但它已被本机 asp.net 会话管理器删除。(asp.net 会话对象已删除)。该问题在本地/环境中不可重现。仅发生在生产环境中。
    • 是什么让您认为这是@ONURDİKMEN 的原因?即使会话过期,您也不应该看到您看到的异常。该异常的最常见原因是对 Session 对象的多线程访问。见stackoverflow.com/questions/24987909/…
    • 这类问题(竞争条件/多线程问题)在生产中总是更容易发生,纯粹是由于负载(即更多的用户,更多的东西执行)。
    • 如果单个 Web 请求导致多个线程运行并访问 Session 对象,事情就会中断。没有办法解决它 - 它的设计不是线程安全的。我将添加一些代码以考虑使用。
    【解决方案2】:

    故障堆栈跟踪如下

    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] 
    

    【讨论】:

    • 把这个放在你原来的帖子里,而不是作为答案。
    猜你喜欢
    • 2011-04-17
    • 2012-10-21
    • 2012-04-23
    • 2016-07-16
    • 1970-01-01
    • 1970-01-01
    • 2011-01-10
    • 2010-12-29
    • 1970-01-01
    相关资源
    最近更新 更多