BackgroundWorker & Timer, vous ne lisez que les nouvelles lignes d’un fichier journal?

Mon application écrit un fichier journal (en utilisant actuellement log4net ). J’aimerais configurer un minuteur et un agent d’arrière-plan pour lire le fichier journal et en imprimer le contenu dans un certain contrôle de ma fiche, pendant son écriture.

Je ne peux pas utiliser la classe FileSystemWatcher car cela semble cassé: parfois l’événement “modifié” se déclenche, parfois pas. Et son taux de mise en commun est extrêmement faible.

J’ai donc créé un minuteur et un FileSystemWatcher. Sur l’événement “tick” du minuteur, l’agent d’arrière-plan fait son travail.

La question qui se pose est la suivante: comment lire uniquement les lignes ajoutées depuis la dernière vérification du travailleur?

public LogForm() { InitializeComponent(); logWatcherTimer.Start(); } private void logWatcherTimer_Tick(object sender, EventArgs e) { FileInfo log = new FileInfo(@"C:\log.txt"); if(!logWorker.IsBusy) logWorker.RunWorkerAsync(log); } private void logWorker_DoWork(object sender, DoWorkEventArgs e) { // Read only new lines since last check. FileInfo log = (FileInfo) e.Argument; // Here is the main question! } 

EDIT: Code Solution (peut-être qu’il y a un moyen plus élégant?):

 private void logWatherWorker_DoWork(object sender, DoWorkEventArgs e) { // retval ssortingng newLines = ssortingng.Empty; FileInfo log = (FileInfo) e.Argument; // Just skip if log file hasn't changed if (lastLogLength == log.Length) return; using (StreamReader stream = new StreamReader(log.FullName)) { // Set the position to the last log size and read // all the content added stream.BaseStream.Position = lastLogLength; newLines = stream.ReadToEnd(); } // Keep track of the previuos log length lastLogLength = log.Length; // Assign the result back to the worker, to be // consumed by the form e.Result = newLines; } 

Vérifiez et enregistrez la taille du fichier chaque fois que vous lisez le journal, puis démarrez votre lecteur de texte (ou ce que vous utilisez) à cet emplacement lors de votre prochaine lecture.

Vous pouvez suivre l’index du dernier caractère lu dans le stream et seek ensuite cette position.

Edit: voir http://dotnetperls.com/seek pour des exemples.

Si tout ce que vous voulez, c’est visualiser votre fichier journal sur un formulaire au moment de son écriture, pourquoi ne pas faire quelque chose de simple, comme écrire votre propre Appender, qui est sauvegardé par une zone de texte, une zone de texte, une table RichTextBox, etc.

Voici quelques liens que j’ai trouvés juste en faisant une recherche rapide sur Google pour “log4net textbox appender”:

http://www.nimblecoder.com/blog/archive/2009/01/30/using-a-delegate-and-custom-appender-with-log4net-to-display.aspx (Celui-ci est plutôt cool parce qu’il permet vous devez spécifier un délégué à exécuter sur chaque message de journal afin que vous ne soyez même pas lié à une zone de texte (vous pouvez écrire des delegates différents en fonction de l’endroit où vous souhaitez que la sortie du journal aille).

http://www.l4ndash.com/Log4NetMailArchive%2Ftabid%2F70%2Fforumid%2F1%2Fpostid%2F15133%2Fview%2Ftopic%2FDefault.aspx

http://weblogs.asp.net/psteele/archive/2010/01/25/live-capture-of-log4net-logging.aspx

http://www.l4ndash.com/Log4NetMailArchive%2Ftabid%2F70%2Fforumid%2F1%2Fpostid%2F14923%2Fview%2Ftopic%2FDefault.aspx (il s’agit d’un appelant qui déclenche un événement pour chaque message enregistré).

http://markmail.org/message/ma62bdjpmab3cn7y (relativement récent – publié en 2008 – utilise RichTextBox pour générer une sortie de style ColoredConsoleAppender)

http://www.claassen.net/geek/blog/2005/06/log4net-scrollingtextbox.html (Celui-ci utilise le MemoryAppender pour capturer les messages du journal, puis les écrit dans une zone de texte)

http://code.google.com/p/devdefined-tools/source/browse/trunk/projects/common/DevDefined.Common/Appenders/TextBoxAppender.cs?r=90

Je n’ai essayé aucune de ces solutions, je ne peux donc pas en garantir la qualité. Mais, je pense que l’utilisation d’un Appender personnalisé soutenu par une zone de texte semble être une approche bien meilleure que d’essayer de regarder le fichier journal, de le lire, puis de placer les messages dans une zone de texte.

Quelques thèmes communs que j’ai remarqués en regardant brièvement ces appendices:

  1. Lorsque vous écrivez dans la zone de texte à partir d’Appender, vous devrez peut-être utiliser BeginInvoke.

  2. Une partie délicate semble indiquer à l’Appender à quelle TextBox écrire. Dans la plupart des cas, Appender est configuré via le fichier de configuration, puis la zone de texte est ajoutée à Appender par programme APRÈS l’initialisation du système de journalisation (je pense que vous devez récupérer au moins un journal ou vous connecter au moins un message pour forcer tous les utilisateurs. d’initialisation paresseuse).

  3. Faites attention à ne pas append constamment de lignes à la zone de texte. Vous pourriez utiliser beaucoup de mémoire, causer des problèmes de performances ou dépasser la limite autorisée dans la zone de texte (le cas échéant). Plusieurs de ces appendices incluent du code qui supprime périodiquement les “anciennes” lignes de la zone de texte.