Question

J'ai un problème intermittent avec du code qui écrit dans un journal des événements Windows, à l'aide de la classe EventLog de C # et .Net.

En gros, ce code fonctionne parfaitement au jour le jour, mais très rarement, nous commençons à avoir des erreurs comme celle-ci:

  

" System.ArgumentException: uniquement les   huit premiers caractères d'un journal personnalisé   nom sont importants, et il y a   déjà un autre journal sur le système   en utilisant les huit premiers caractères de   le nom donné. Nom donné:   'Application', nom du journal existant:   "Application". "

Je peux identifier, à partir des autres informations de nos journaux, que la pile d'appels affectée est la suivante: vous voyez clairement que je suis en train d'écrire dans un journal LB_Email existant ( LogEmail est appelé en premier):

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

Une fois que les erreurs commencent à se produire, il semble que l'accès à notre journal d'événements LB_Email soit verrouillé - l'affichage des propriétés du journal des événements en particulier indique que la plupart des informations sont grisées et non modifiables, mais que d'autres processus semblent être empêchés. de se connecter à ce journal aussi. Cependant, je vois l'erreur (qui utilise la même méthode Log ci-dessus) via un try-catch qui enregistre dans un journal "LB_Error" et qui continue à fonctionner comme prévu.

J'appelle ce code à partir d'une application multithread, mais je n'ai pas pu déterminer si le code ci-dessus est thread-safe ou non.

Je peux également confirmer que le journal en question fonctionne à nouveau correctement après la suppression et le redémarrage du processus ... et qu'il disposait des paramètres appropriés pour réutiliser les entrées lorsqu'il était plein ... bien que je ne pense pas que ce soit le problème .

J'aimerais connaître vos pensées et vos suggestions.

Était-ce utile?

La solution

La documentation indique que:

  

Vous pouvez uniquement utiliser la source pour écrire   à un journal à la fois

Je suppose donc que ce problème est dû au fait que votre application multithread appelle la méthode Log plusieurs fois à la fois et pour la même source.

Je suggère qu'au lieu d'utiliser une classe statique (ou des méthodes), vous utilisiez une classe singleton thread-safe pour consigner ces événements.

EDIT:

Jon Skeet a publié un article excellent sur les singletons.

Si vous ne souhaitez pas implémenter une classe singleton, vous pouvez faire quelque chose comme ceci:

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

J'espère que cela résoudra votre problème.

Autres conseils

Merci Bruno,

Je me trompe donc en pensant que l'instance EventLog dans la méthode Log est différente de l'instance EventLog dans le même appel de méthode dans un thread différent? Ou suis-je en train de confondre les instances d'objet dans une méthode statique?

OK, j'ai donc plusieurs méthodes d'emballage pour la méthode Log (...). Si j'ai déplacé la méthode Log dans une classe singleton, modifié les wrappers (LogEmail, LogXxxx, LogYyy, etc.), je pouvais conserver les mêmes interfaces Log.Zzzz, tout en optimisant la sécurité du singleton LogSingleton.Instance.Log (...) depuis les journaux actuels OU parce que je veux écrire dans différents journaux, chacun d’entre eux a-t-il besoin de son propre LogSingletonXxx?

Vous pouvez dire que je suis confus :) Oui, j'apprécierais vraiment un code de synchronisation:)

Nij

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top