2010-11-22 14 views
4

Ich habe eine Website, die in ASP.NET 3.5, NHibernate 2.2 und Sprint .NET für Dependency Injection ausgeführt wird. Auf unserem Testserver tritt ein ziemlich seltsamer Fehler auf, und auch fast immer, wenn mehrere Benutzer online sind. Nachdem das Problem aufgetreten ist, wird dieser Fehler für jeden Benutzer und jede Anforderung angezeigt - bis Sie ein IISRESET ausführen. Dann ist alles wieder in Ordnung.Sonderfehler: [ArgumentOutOfRangeException: 'count' muss nicht negativ sein

Hier ist die Ausnahme:

'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 

Antwort

3

Dies ist in der Tat ein sehr seltsamer Fehler. Wenn Sie den Blick auf die Quelle AbstractObjectFactory.GetObjectInternal Sie die folgende Struktur sehen:

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

Die Ausnahme Sie sehen, von einem der drei new String(' ', nestingCount * INDENT) Anrufe geworfen werden müssen. Dieser spezielle string Konstruktoraufruf löst aus, wenn der angegebene Wert negativ ist. Weil INDENT eine Konstante ist, muss nestingCount in diesem Fall einen negativen Wert haben. nestingCount ist eine thread-statische Variable. Thread-statische Variablen werden immer mit ihrem Standardwert (in diesem Fall 0) initialisiert und können nicht von anderen Threads beeinflusst werden. Weiter wird nestingCount nie außerhalb dieser Methode verwendet.

Da nestingCount Thread-statisch ist und nur in dieser Methode verwendet wird, ist es schwer, sich ein Szenario vorzustellen, in dem nestingCount negativ werden kann. Vielleicht im Falle einer asynchronen (ThreadAbort) Ausnahme, aber selbst das ist mir schwer vorstellbar. Eine andere Option ist, dass die thread-statische Variable von jemand anderem durch Reflektion geändert wird.

Aber die große Frage ist: Wie löst man das?

Lösung:

Es gibt nur eine Sache, die ich mir vorstellen kann, und das ist neu konfigurieren log4net in einer Weise, die Informationen debuggen nicht angemeldet ist. Wenn die Debug-Informationen nicht akzeptiert werden, wird der string(char, int)-Konstruktor wahrscheinlich nie wieder aufgerufen, wodurch das Problem verdeckt wird. Nicht sehr hübsch, aber möglicherweise effektiv. Dies könnte funktionieren, weil die AbstractObjectFactory Protokolle die log Variable, die initialisiert wird, wie folgt:

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

Sie diese global tun können, durch das Schreiben von Debug-Informationen in log4net zu deaktivieren, oder -wenn Sie denken, dies ist overkill- durch Konfigurieren von log4net, um Debug-Informationen für den Typ Spring.Objects.Factory.Support.DefaultListableObjectFactory (die Instanz, die die Ausnahme verursacht) zu deaktivieren.

Viel Glück.

+0

Das Debuggen für Spring.Objects.Factory.Support.DefaultListableObjectFactory ist eine Idee, die funktionieren könnte. Ich werde das versuchen und sehen, dass der Fehler nicht wieder auftritt. Der Fehler ist definitiv komisch, aber ziemlich interessant. Hoffentlich ist die Grundursache nur auf diesen Fehler beschränkt ... Danke Steven! Ich werde den Beitrag auf dem Laufenden halten, wenn etwas Neues auftaucht. – Mattias

+0

@Mattias: Ich bin sehr neugierig, ob meine Beobachtungen korrekt waren und ob die Deaktivierung des Debugging tatsächlich Ihr Problem gelöst hat. – Steven

+0

Hoffentlich kann ich Ihnen in Kürze eine Antwort geben. Dies geschieht nur auf dem Produktionsserver, der noch nicht live geschaltet wurde. Also nach dem nächsten Update werden wir sehen. – Mattias

0

ich diesen Fehler gesehen auftreten, wenn eine Datenbankspalte auf mehr als eine Eigenschaft zugeordnet ist. Ein typischer Fall ist, wenn eine Fremdschlüsselspalte einer Eigenschaft und einer Sammlung zugeordnet wird. Ein zweites oder drittes Augenpaar in den Konfigurationsdateien hilft dabei, diese zu erkennen.

Eine Wendung mit diesem ist, dass es für alle Benutzer auftritt. Haben Sie ein persistentes Objekt, das im Anwendungszustand gespeichert ist?

+0

Ich kann den gesamten Code aufgrund der Vertraulichkeit nicht veröffentlichen, aber das Objekt, das gefunden wird, ist ein internes Objekt mit einer ISession und einem ExceptionHandler als Konstruktorargumente. Der Fehler wird angezeigt, wenn das Objekt initialisiert wird. – Mattias

0

In meinem Fall trat dieser Fehler nach einiger Zeit während des Leistungstests auf. Es beginnt gut und nach einiger Zeit erscheint dieser Fehler.

Es stellte sich heraus, dass es durch eine völlig unabhängige Variable [ThreadLocal] verursacht wurde, die ich in meinem Code verwendete. Ich ersetzte es durch einen Methodenparameter und jetzt funktioniert es gut.

Verwandte Themen