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

发布于 2024-10-04 03:23:54 字数 2115 浏览 0 评论 0原文

我有一个在 ASP.NET 3.5、NHibernate 2.2 和 Sprint .NET 中运行的网站,用于依赖注入。在我们的测试服务器上,几乎每次有多个用户在线时都会发生一个相当奇怪的错误。问题发生后,每个用户及其发出的每个请求都会显示此错误 - 直到您执行 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

I have a site which runs in ASP.NET 3.5, NHibernate 2.2 and Sprint .NET for Dependency Injection. On our test server a rather strange error occurrs, and also almost everytime there are multiple users online. After the problem has occurred, this error is displayed for every user and every request they make - until you do an IISRESET. Then it is all ok again.

Here's the exception:

'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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

近箐 2024-10-11 03:23:54

这确实是一个非常奇怪的错误。当您查看 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 是一个常量,因此在这种情况下 nestingCount 必须具有负值。 nestingCount 是一个线程静态变量。线程静态变量始终使用默认值(本例中为 0)进行初始化,并且不会受到其他线程的影响。此外,nestingCount 永远不会在该方法之外使用。

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

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

解决方案:

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

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

您可以通过在 log4net 中全局禁用调试信息写入来实现此目的,或者 –when您认为这太过分了 - 通过配置 log4net 来禁用 Spring.Objects.Factory.Support.DefaultListableObjectFactory 类型的调试信息(实际上导致异常的实例)。

祝你好运。

This is indeed a very wierd error. When you look at the source of the AbstractObjectFactory.GetObjectInternal you will see the following structure:

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

The exception you are seeing must be thrown by one of the three new String(' ', nestingCount * INDENT) calls. That particular string constructor call throws when the supplied value is negative. Because INDENT is a const, nestingCount must have a negative value in that case. nestingCount is a thread-static variable. Thread-static variables are always initialized with their default value (0 in this case) and can't be influenced by other threads. Further more, nestingCount is never used outside this method.

Because nestingCount is thread-static and only used in that method, it is hard to imagine a scenario were nestingCount can get negative. Perhaps in the case of an asynchronous (ThreadAbort) exception, but even this I find hard to imagine. Other option is that the thread-static variable is changed by someone else using reflection.

But the big question is: how to solve this?

Solution:

There's only one thing I can think of and that is reconfigure log4net in a way that debug information isn't logged. When disallowing debug information, the string(char, int) constructor will probably never get called again, which will hide the problem. Not very pretty, but possibly effective. This might work, because the AbstractObjectFactory logs using the log variable that is initialized as follows:

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

You can do this by globally disabling the writing of debug information in log4net, or –when you think this is overkill- by configuring log4net to disable debug info for the type Spring.Objects.Factory.Support.DefaultListableObjectFactory (the instance that is actually causes the exception).

Good luck.

天暗了我发光 2024-10-11 03:23:54

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

与此不同的是,所有用户都会发生这种情况。您是否有存储在应用程序状态中的持久对象?

I have seen this error occur when a database column is mapped to more than one property. A typical case is when a foreign key column is mapped to a property and to collection. A second or third pair of eyes on the config files helps spot these.

One twist with this is that it occurs for all users. Do you have a persistent object that is stored in application state?

雪若未夕 2024-10-11 03:23:54

就我而言,这个错误是在性能测试一段时间后发生的。它开始正常,一段时间后会弹出此错误。

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

In my case, this error occurred after some time during performance testing. It starts fine and after some time this error pops up.

Turns out it was caused by a totally unrelated [ThreadLocal] variable I used in my code. I replaced it with a method parameter and now it works fine.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文