Domanda

Ho un problema intermittente con del codice che scrive in un registro eventi di Windows, usando la classe EventLog di C # e .Net.

Fondamentalmente, questo codice funziona perfettamente ogni giorno, ma molto occasionalmente, iniziamo a ricevere errori come questo:

  

" System.ArgumentException: solo il file   primi otto caratteri di un registro personalizzato   il nome è significativo, e c'è   già un altro registro sul sistema   usando i primi otto caratteri di   il nome dato. Nome dato:   "Applicazione", nome del registro esistente:   . 'Application' "

Sono in grado di identificare dalle altre informazioni sui nostri registri che lo stack di chiamate interessato è in questo modo - Puoi chiaramente vedere che sto effettivamente cercando di scrivere in un registro LB_Email esistente ( LogEmail viene chiamato per primo):

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 volta che si verificano gli errori, sembra che l'accesso al nostro registro eventi LB_Email sia bloccato in qualche modo - la visualizzazione delle proprietà sul particolare registro eventi mostra la maggior parte delle informazioni in grigio e immutabili, e altri processi sembrano essere prevenuti dalla registrazione anche a quel registro. Tuttavia, visualizzo l'errore (che utilizza lo stesso metodo di registro sopra) tramite un try-catch che accede a un registro "LB_Error" e che continua a funzionare come previsto.

Sto chiamando questo codice da un'applicazione multi-thread, ma non sono stato in grado di identificare se il codice sopra è thread-safe o meno.

Posso anche confermare che il login in questione sta funzionando di nuovo bene dopo aver ucciso e riavviato il processo ... e aveva le impostazioni appropriate per riutilizzare le voci quando era pieno ... anche se non penso che fosse il problema .

Mi piacerebbe sentire i tuoi pensieri e suggerimenti.

È stato utile?

Soluzione

La documentazione afferma che:

  

Puoi solo usare la Fonte per scrivere   a un registro alla volta

Quindi sospetto che questo problema sia causato dalla tua app multithread che chiama il metodo Log più di una volta in un dato momento e per la stessa fonte.

Suggerisco che, anziché una classe statica (o metodi), usi una classe singleton thread-safe per registrare questi eventi.

EDIT:

Jon Skeet ha un eccellente articolo sui singoli.

Se non vuoi implementare una classe singleton puoi fare qualcosa del genere:

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

Spero che questo risolva il tuo problema.

Altri suggerimenti

Grazie Bruno,

Quindi, sbaglio nel pensare che l'istanza EventLog nel metodo Log sia diversa dall'istanza EventLog nella stessa chiamata del metodo in un thread diverso? O mi sto solo confondendo sulle istanze di oggetti all'interno di un metodo statico?

OK, quindi ho diversi metodi wrapper per il metodo Log (...). Se spostassi il metodo Log in una classe singleton, cambiassi i wrapper (LogEmail, LogXxxx, LogYyy ecc., Allora potrei mantenere le mie interfacce Log.Zzzz uguali, ma sfruttare la sicurezza del singleton LogSingleton.Instance.Log (...) dai registri correnti. O poiché desidero scrivere in registri diversi, ognuno richiederebbe il proprio LogSingletonXxx?

Puoi dire che sono confuso :) Sì, apprezzerei molto il codice di sincronizzazione :)

Nij

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top