2010-11-30 9 views
10

Mi aplicación escribe un archivo de registro (actualmente usa log4net). Me gustaría configurar un temporizador y un trabajador de segundo plano para leer el archivo de registro e imprimir su contenido con cierto control en mi formulario, mientras se está escribiendo.BackgroundWorker & Timer, leyendo solo nuevas líneas de un archivo de registro?

No puedo usar la clase FileSystemWatcher porque parece estar rota: a veces el evento "cambia" los incendios, a veces no. Y tiene una "tasa de puesta en común" extremadamente baja.

Así que creé un Timer y un FileSystemWatcher. En el evento "marcar" del temporizador, el trabajador de segundo plano hace su trabajo.

La pregunta es: cómo leer solo las líneas que se agregan desde la última comprobación del trabajador?

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: Solución Código (tal vez hay una forma más elegante?):

private void logWatherWorker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    // retval 
    string newLines = string.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; 
} 

Respuesta

2

Comprobar y almacenar el tamaño del archivo cada vez que lea el registro, a continuación, iniciar su texto lector (o lo que sea que esté usando) en esa ubicación la próxima vez que lea.

+0

Elegí tu camino, muchas gracias. He editado la primera publicación para incluir la solución de código. – gremo

+0

muchas gracias por publicar la solución –

2

Puede realizar un seguimiento del índice del último carácter leído de la secuencia y, posteriormente, seek en esa posición.

Editar: vea http://dotnetperls.com/seek para ver ejemplos.

2

Si todo lo que quiere es ver su archivo de registro en un formulario tal como está siendo escrito, ¿por qué no hacer algo tan simple como escribir su propio Appender respaldado por un TextBox, RichTextBox o lo que sea?

Éstos son algunos enlaces que he encontrado sólo haciendo una rápida búsqueda en Google de "log4net cuadro de texto appender":

http://www.nimblecoder.com/blog/archive/2009/01/30/using-a-delegate-and-custom-appender-with-log4net-to-display.aspx (Éste se ve muy bien, ya que le permite especificar un delegado para ejecutar en cada mensaje de registro, por lo que ni siquiera estarías atado a un TextBox. Podrías escribir diferentes delegados dependiendo de dónde quisieras que fuera tu salida de registro).

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 (Éste es un Appender de que provoca un evento por cada mensaje que se registra).

http://markmail.org/message/ma62bdjpmab3cn7y (relativamente reciente - publicado en 2008 - utiliza RichTextBox generada de salida de estilo ColoredConsoleAppender)

http://www.claassen.net/geek/blog/2005/06/log4net-scrollingtextbox.html (Esto se usa el MemoryAppender para capturar los mensajes de registro y luego escribe los mensajes a un cuadro de texto)

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

No he probado ninguno de estos, por lo que no puedo responder por su calidad. Pero, creo que el enfoque de utilizar un Appender personalizado respaldado por un TextBox parece ser un enfoque mucho mejor que tratar de ver el archivo de registro, leerlo y luego colocar los mensajes en un TextBox.

algunos temas comunes que he notado mientras mira brevemente sobre estos appenders:

  1. Al escribir en el cuadro de texto de la Appender de, puede que tenga que utilizar BeginInvoke.

  2. Una parte engañosa parece decirle al Appender en qué cuadro de texto escribir. En la mayoría de los casos, el Appender se configura a través del archivo de configuración y luego se agrega el TextBox al Appender programmatically DESPUÉS de que el sistema de registro se haya inicializado (creo que debe recuperar al menos un registrador o registrar al menos un mensaje para forzar de la inicialización perezosa a suceder).

  3. Tenga cuidado al agregar constantemente líneas al TextBox. Podría consumir mucha memoria, causar problemas de rendimiento o exceder el límite en el TextBox (si hay uno). Varios de estos Anexos incluyen código que elimina periódicamente líneas "viejas" del TextBox.

+0

Wow. Olvidé cuánto log4net complica la simple tarea de escribir mierda en un archivo de texto. :) – MusiGenesis

Cuestiones relacionadas