Pregunta

Tengo un problema intermitente con algún código que escribe en un Registro de eventos de Windows, usando C # y la clase EventLog de .Net.

Básicamente, este código funciona día a día perfectamente, pero muy ocasionalmente, comenzamos a recibir errores como este:

  

" System.ArgumentException: solo el   primeros ocho caracteres de un registro personalizado   nombre son significativos, y hay   ya otro registro en el sistema   usando los primeros ocho caracteres de   El nombre dado. Nombre dado:   'Aplicación', nombre del registro existente:   'Aplicación'. & Quot;

Puedo identificar a partir de la otra información en nuestros registros que la pila de llamadas afectada es así: puede ver claramente que de hecho estoy tratando de escribir en un registro existente de LB_Email ( LogEmail se llama primero):

public static void LogEmail(string to, string type)
{
    string message = String.Format("{0}\t{1}\t{2}", DateTime.Now, to, type);
    Log(message, "LB_Email", EventLogEntryType.Information);
}

private static void Log(string message, string logName, EventLogEntryType type)
{
    using (EventLog aLog = new EventLog())
    {
        aLog.Source = logName;
        aLog.WriteEntry(message, type);
    }
}

Una vez que comienzan a ocurrir los errores, parece que el acceso a nuestro registro de eventos LB_Email está bloqueado de alguna manera: las propiedades de visualización en el registro de eventos en particular muestran que la mayoría de la información aparece atenuada e inmutable, y parece que se evitan otros procesos de iniciar sesión en ese registro también. Sin embargo, estoy viendo el error (que usa el mismo método de registro anterior) a través de un try-catch que se registra en un registro 'LB_Error', y que continúa funcionando como se esperaba.

Llamo a este código desde una aplicación multiproceso, pero no he podido identificar si el código anterior es seguro para subprocesos o no.

También puedo confirmar que la pregunta de inicio de sesión está funcionando nuevamente bien después de finalizar y reiniciar el proceso ... y tenía la configuración adecuada para reutilizar las entradas cuando se llenó ... aunque no creo que ese sea el problema .

Me encantaría escuchar tus pensamientos y sugerencias.

¿Fue útil?

Solución

La documentación establece que:

  

Solo puedes usar la Fuente para escribir   a un registro a la vez

Entonces sospecho que este problema es causado por su aplicación multiproceso que llama al método Log más de una vez en un momento dado y para la misma Fuente.

Sugiero que, en lugar de una clase estática (o métodos), utilice una clase singleton segura para subprocesos para registrar estos eventos.

EDITAR:

Jon Skeet tiene un excelente artículo sobre singletons.

Si no desea implementar una clase singleton, puede hacer algo como esto:

    static readonly object lockObj = new object();

    public static void LogEmail(string to, string type)
    {
        string message = String.Format("{0}\t{1}\t{2}", DateTime.Now, to, type);
        Log(message, "LB_Email", EventLogEntryType.Information);
    }

    private static void Log(string message, string logName, EventLogEntryType type)
    {
        lock (lockObj)
        {
            using (EventLog aLog = new EventLog())
            {
                aLog.Source = logName;
                aLog.WriteEntry(message, type);
            }
        }
    }

Espero que esto resuelva tu problema.

Otros consejos

Gracias Bruno,

Entonces, ¿me equivoco al pensar que la instancia de EventLog en el método Log es diferente de la instancia de EventLog en la misma llamada al método en un hilo diferente? ¿O simplemente me estoy confundiendo acerca de las instancias de objetos dentro de un método estático?

OK, entonces tengo varios métodos de envoltura para el método Log (...). Si moví el método Log a una clase singleton, cambié los contenedores (LogEmail, LogXxxx, LogYyy, etc., entonces podría mantener mis interfaces Log.Zzzz iguales, pero aprovechar la seguridad de Singleton LogSingleton.Instance.Log (...) de los registros actuales. O porque quiero escribir en diferentes registros, ¿requeriría cada uno su propio LogSingletonXxx?

Puedes decir que estoy confundido :) Sí, realmente agradecería algún código de sincronización :)

Nij

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top