奇怪的错误:[ArgumentOutOfRangeException:'count'必须是非负的

时间:2010-11-22 15:00:06

标签: asp.net nhibernate orm dependency-injection spring.net

我有一个运行在ASP.NET 3.5,NHibernate 2.2和Sprint .NET for Dependency Injection的站点。在我们的测试服务器上发生了一个相当奇怪的错误,并且几乎每次有多个用户在线时。问题发生后,每个用户及其发出的每个请求都会显示此错误 - 直到您执行IISRESET。然后一切都好了。

以下是例外:

'count' must be non-negative.
Parameter name: count 
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.ArgumentOutOfRangeException: 'count' must be non-negative.
Parameter name: count

Source Error: 
[No relevant source lines]

Source File: c:\Windows\Microsoft.NET\Framework64\v2.0.50727\Temporary ASP.NET      Files\root\4bf9aa39\6dcf5fc6\App_Web_z9ifuy6t.6.cs    Line: 0 

Stack Trace: 
[ArgumentOutOfRangeException: 'count' must be non-negative.
Parameter name: count]
System.String.CtorCharCount(Char c, Int32 count) +10082288
Spring.Objects.Factory.Support.AbstractObjectFactory.GetObjectInternal(String name, Type requiredType, Object[] arguments, Boolean suppressConfigure) +3612
Spring.Objects.Factory.Support.AbstractObjectFactory.GetObject(String name) +75
Spring.Objects.Factory.Support.DefaultListableObjectFactory.GetObjectsOfType(Type type, Boolean includePrototypes, Boolean includeFactoryObjects) +365
Spring.Context.Support.AbstractApplicationContext.GetObjectsOfType(Type type, Boolean includePrototypes, Boolean includeFactoryObjects) +136
Spring.Context.Support.AbstractApplicationContext.GetObjectsOfType(Type type) +66


[ActivationException: Activation error occured while trying to get instance of type InfoTextService, key ""]
   Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance(Type serviceType, String key) in      c:\Home\Chris\Projects\CommonServiceLocator\main\Microsoft.Practices.ServiceLocation\ServiceLocatorImplBase.cs:57
Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance() in c:\Home\Chris\Projects\CommonServiceLocator\main\Microsoft.Practices.ServiceLocation\ServiceLocatorImplBase.cs:90
OurProjectsNamespace.Infrastructure.ObjectLocator.LocateService() +86

3 个答案:

答案 0 :(得分:3)

这确实是一个非常奇怪的错误。当您查看AbstractObjectFactory.GetObjectInternal的来源时,您将看到以下结构:

[ThreadStatic]
private int nestingCount;

protected object GetObjectInternal(...)
{
    const int INDENT = 3;
    bool hasErrors = false;
    try
    {
        nestingCount++;

        if (log.IsDebugEnabled)
        {
            log.Debug("msg" + 
                new String(' ', nestingCount * INDENT));
        }

        // More code: Calls self recursively.
    }
    catch
    {
        nestingCount--;
        hasErrors = true;

        if (log.IsErrorEnabled)
        {
            log.Error("msg" + 
                new String(' ', nestingCount * INDENT));
        }        
    }
    finally
    {
        if (!hasErrors)
        {
            nestingCount--;
            if (log.IsDebugEnabled)
            {
                log.Debug("msg" + 
                    new String(' ', nestingCount * INDENT));
            }        
        }
    }
}

您看到的异常必须由三个new String(' ', nestingCount * INDENT)调用之一抛出。当提供的值为负时,该特定string构造函数调用将抛出。由于INDENT是const,因此nestingCount必须具有负值。 nestingCount是一个线程静态变量。线程静态变量始终使用其默认值进行初始化(在本例中为0),并且不受其他线程的影响。此外,nestingCount从未在此方法之外使用。

由于nestingCount是线程静态的并且仅在该方法中使用,因此很难想象nestingCount的情况可能会变为负数。也许在异步(ThreadAbort)异常的情况下,但即使这样我也很难想象。其他选项是使用反射由其他人更改线程静态变量。

但最大的问题是:如何解决这个问题?

<强>解决方案:

我只能想到一件事,那就是以不记录调试信息的方式重新配置log4net。禁用调试信息时,string(char, int)构造函数可能永远不会再被调用,这将隐藏问题。不是很漂亮,但可能有效。这可能有效,因为使用AbstractObjectFactory变量的log日志初始化如下:

this.log = LogManager.GetLogger(this.GetType());

您可以通过全局禁用log4net中的调试信息写入来执行此操作,或者 - 如果您认为这是过度的 - 通过配置log4net来禁用类型Spring.Objects.Factory.Support.DefaultListableObjectFactory的调试信息(实际导致该实例的实例)除外)。

祝你好运。

答案 1 :(得分:0)

我已经看到当数据库列映射到多个属性时会发生此错误。典型情况是外键列映射到属性和集合。配置文件中的第二对或第三对眼睛有助于发现这些。

这样做的一个转折是它适用于所有用户。你有一个存储在应用程序状态的持久对象吗?

答案 2 :(得分:0)

就我而言,在性能测试期间发生了一段时间后发生此错误。它开始很好,一段时间后会弹出这个错误。

原来它是由我在代码中使用的完全不相关的[ThreadLocal]变量引起的。我用方法参数替换它,现在它工作正常。