He tenido un asp.net sitio web funcionando en vivo en nuestra intranet para un par de semanas. Acabo de recibir un correo electrónico de mi application_error emailer método con una excepción no controlada.

Aquí es (he limpiado algunos de los caminos para hacerlo mejor muestra)

Excepción : referencia a Objeto no establecida como instancia de un objeto.
Seguimiento de la pila : en el Sistema.Las colecciones.Genérica.Diccionario`2.Insertar(TKey clave, TValue valor, Boolean add) en el Sistema.Las colecciones.Genérica.Diccionario`2.Agregar(TKey clave, TValue valor)
en TimesheetDomain.DataMappers.StaffMemberData.ReadStaff(SqlDataReader lector) en TimesheetDomain\DataMappers\StaffMemberData.cs:línea 362

a
TimesheetDomain.DataMappers.StaffMemberData.GetStaffMember(String
nombre) en
TimesheetDomain\DataMappers\StaffMemberData.cs:línea
401

a
TimesheetDomain.ServiceLayer.TimesheetManager.GetUserFromName(String
nombre) en
TimesheetDomain\ServiceLayer\TimesheetManager.cs:línea
199

a UserVerification.GetCurrentUser()
en \App_Code\UserVerification.cs:línea
29 en WebTimesheets.OnInit(EventArgs
e) en
\WebTimesheets\WebTimesheets.maestro.cs:línea
159

a
Sistema.Web.La interfaz de usuario.De Control.InitRecursive(Control De
namingContainer) en
Sistema.Web.La interfaz de usuario.De Control.InitRecursive(Control De
namingContainer) en
Sistema.Web.La interfaz de usuario.Página.ProcessRequestMain(Boolean
includeStagesBeforeAsyncPoint, Boolean
includeStagesAfterAsyncPoint)

Parece que es erroring en mi ReadStaff método que lee un lector de datos para construir miembro del personal de objetos. Aquí está el trozo de código:

while (reader != null && reader.Read())
{
    StaffMember newMember = null;
    string firstName = reader["FirstName"].ToString();
    string lastName = reader["LastName"].ToString();
    int staffID = (int)reader["StaffID"];
    int employSection = (int)reader["EmploySection"];
    StaffType employType = (StaffType)employSection;
    string emailAddress = reader["EmailInt"].ToString();
    int employCode = (int)reader["ibbwid"];

    //check if they are an admin staff member 
    if (IsAdminStaff(employType))
    {
        newMember = new AdminOfficer(firstName, lastName, employType, staffID, emailAddress, employCode);
    }
    else
    {
        //check if they are a supervisor
        if (IsASupervisor(staffID))
            newMember = new Supervisor(firstName, lastName, employType, staffID, emailAddress, employCode);
        else
            newMember = new StaffMember(firstName, lastName, employType, staffID, emailAddress, employCode);
    }

    //add to identity map
    if (!_staffMembers.ContainsKey(staffID))
        _staffMembers.Add(staffID, newMember); //****THIS IS LINE 362*****
    else
        _staffMembers[staffID] = newMember;
}

(Línea 362 es 3ª última línea)
Estoy usando un mapa de identidad (acabo de leer fowlers libro sobre patrones y pensé que era una buena idea – puede haber hecho mal, feliz por los comentarios), pero que no es demasiado relevante como más tarde yo uso el newMember objeto de otros lugares por lo que si puedo quitar el bloque NullReferenceException va a ocurrir.

Estoy luchando para ver cómo en la tierra newMember es nulo en el 3er última línea (que es la línea que se produjo un error).

Resharper/VS no me da una advertencia de que podría ser null – porque no hay el 3 de constructores que puedo elegir.

Puede alguien sugerir donde puedo mirar para intentar solucionar este error? Que sólo ocurrió una vez y que el método ha sido llamado miles de veces desde que el sitio fue vivo.

Gracias

[EDITAR]
Conforme a lo Solicitado, aquí está el IComparer por miembro del personal

///<summary>
///Comparer for staff members - compares on name
///</summary>
public class StaffMemberComparer : IComparer
{
    public int Compare(object x, object y)
    {
        //check they are staff members
        if (x is StaffMember && y is StaffMember)
        {
            //do a simple string comparison on names
            StaffMember staffX = x as StaffMember;
            StaffMember staffY = y as StaffMember;

            return String.Compare(staffX.FirstName, staffY.FirstName);
        }

        throw new Exception("This is for comparing Staff Members");
    }
}

y que se utiliza en el IComparable aplicación

///<summary>
///IComparable implementaiton
///</summary>
///<param name="obj">object to compare to</param>
///<returns></returns>
public int CompareTo(object obj)
{
    StaffMemberComparer comparer = new StaffMemberComparer();
    return comparer.Compare(this, obj);
}
  • La línea que está TimesheetDomain\DataMappers\StaffMemberData.cs:línea 362?
  • Esto es irrelevante para la pregunta, pero se puede reemplazar todo el if (!_staffMembers.ContainsKey(staffID)) _staffMembers.Add(staffID, newMember); else _staffMembers[staffID] = newMember; con sólo _staffMembers[staffID] = newMember;. Se podría agregar la clave si no existe ya.
  • lo siento (no tenía muy claro) el 362 línea es la 3ª última línea en el bloque de código, su _staffMembers.Agregar(staffID, newMember); gracias mehrdad, me voy a acordar de eso, pensé que lo hizo por una razón, pero no lo recuerdo ahora, así que voy a dar su versión a ir
InformationsquelleAutor RodH257 | 2009-08-24

6 Comentarios

  1. 119

    Es casi ciertamente un problema subprocesamiento – ver esta pregunta y sus aceptado respuesta.

    Dictionary<>.Insert() lanzará una NullReferenceException internamente si el diccionario de la instancia se modifica a partir de otro hilo durante la operación de inserción.

    • Esto es completamente no-obvio, especialmente si sólo se ve una IDictionary desde el exterior…
  2. 18

    Como de .NET 4.0 puede utilizar ConcurrentDictionary y evitar el roscado de los problemas asociados con la manipulación de la misma diccionario de múltiples hilos simultáneamente.

  3. 1

    Que sólo ocurrió una vez y que
    el método ha sido llamado a miles de
    los tiempos desde que el sitio fue vivo.

    Después de leer esto, puedo concluir que es posible que .NET puede haber agotado su memoria y no podía crear más de Diccionario clave, puede no estar realmente en cualquier lugar de su culpa. Pero sí que nos hicieron llegar este tipo de errores cuando intentamos almacenar demasiada información en la sesión/las variables de la aplicación por lo tanto el aumento de la huella en la memoria de la Aplicación Web. Pero tenemos este tipo de errores cuando nuestros números fue muy alta, como el almacenamiento de 10.000 artículos en el Diccionario o Lista, etc.

    El patrón es bueno, pero también debe darse cuenta de que utilizamos la base de datos para almacenar la información en formato relacional, si empezamos a usar la memoria para almacenar cosas similares, entonces estamos ignorando potente base de datos. Base de datos de los valores de caché para usted también.

    Que puede sonar tonto pero tenemos nuestro windows server restart en cada 24 horas, a la medianoche, cuando no hay tráfico. Que nos sirvió en deshacerse de estos errores. Reiniciamos nuestro servidor regularmente en una solución de programación con el fin de obtener toda la caché y los registros de borrado.

  4. 1

    Yo no le veo nada obvio. Me había algunos SQL para consultar la base de datos para cualquier mal los datos. El problema puede ser un monstruo error en un formulario de entrada. Si el código se ha ejecutado miles de veces sin incidentes hasta ahora, me gustaría poner algo de adicionales de manejo de excepciones/informes de todo el bloque de código en cuestión, de manera que usted puede obtener al menos un staffId si/cuando luego sucede.

    Usted podría quemar un montón de tiempo en algo como esto. El más oportuno enfoque puede ser sólo para fracasar de nuevo, en virtud de la/condiciones controladas….. suponiendo que el nivel de interrupción que provoca es aceptable/administrable/menor de edad.

    Agradezco que no satisfacer la necesidad inmediata de saber pero puede ser la mejor manera de manejar el problema, sobre todo con una baja tasa de fracaso.

    • sí, este es probablemente la mejor idea, voy a apretar un poco las cosas y probar y configurar para un mejor mensaje de error y ver si ocurre de nuevo. En realidad no afecta mucho, sólo tendría que actualizar la página, me imagino.
  5. 0

    Como otros han dicho, la comparación podría ser la causa del problema.

    Es alguno de los criterios de comparación contener un valor nulo? específicamente, las propiedades de la cadena?

    es decir, Si el nombre o apellido o emailId es nulo y si es utilizada en la comparación, las cosas pueden fallar cuando se usa en el diccionario para la comparación.

    EDIT: ¿Cómo es el Supervisor y el Miembro y AdminStaff clases?

    En el código, son de fundición de ambas instancias a Miembro. Mi conjetura es que esto podría ser un problema si el Supervisor y el Miembro de la clase son no relacionados.

    EDIT2: ¿Cuál es la scrope del diccionario de la instancia? Es compartida a nivel de aplicación/nivel de sesión? Es posible que varios subprocesos podría intentar leer/escribir de ella?

    • Yo habría pensado que el método CompareTo habría mostrado en la traza de la pila, aunque? Se agrega código principal de correos entiendo tu punto de vista, voy a añadir la comprobación de valores nulos en lastnames, a pesar de que debería ser nulo, se establece en el constructor y devueltos a partir de la base de datos de sql donde se establece como ‘not NULL,’ valores
    • Supervisor y AdminOfficer son los dos tipos de Miembro. Árbol de herencia es: Miembro del Personal Supervisor AdminOfficer un Miembro del Personal puede ser una simple y antiguo Miembro, un Supervisor o un AdminOfficer. El supervisor tiene una lista de StaffMembers, bajo su supervisión, además de las propiedades normales. Ellos están separados, como que principalmente para fines de validación, cuando usted inicie sesión con su nombre de usuario está asociado con un Miembro – si se trata de un Supervisor puede hacer ciertas cosas StaffMembers cant, y usted puede hacer incluso más si eres una AdminOfficer
    • Es un problema de las propiedades de la cadena ser nulo? ¿Agregar la comprobación null? Es la excepción que ocurren después de eso?
    • Gracias por tu aporte shahkalpesh, he añadido el cheque, es un no-repro error aunque (solo tengo 1 correo electrónico hoy en día, el método ha sido llamado miles de veces). Yo no creo que el firstNames puede ser nulo a pesar de que son sacados directamente de la base de datos y la base de datos dissalows valores null en los nombres.
  6. 0

    Otra manera que he visto de esta excepción, sin relación de roscar, es cuando serializar un Diccionario. En este caso, estaba vacía, pero yo todavía tengo el NullReferenceException en el método Insert() en el deserializa instancia.

    El simple cambio en mi caso fue solo para crear una nueva instancia después de deserialización. No estoy seguro de si la serialización se rompe el Diccionario, o si es que los tipos que el Diccionario se define por.

    En mi caso los tipos no fueron serializable sin serialización sustitutos (y me había proporcionado estos), pero tal vez algo en el Diccionario tenido un problema aquí. Sin embargo, el Diccionario estaba vacío y este sucedido todavía.

Dejar respuesta

Please enter your comment!
Please enter your name here