2010-11-30 38 views
10

我的应用程序写入一个日志文件(目前使用log4net)。我想设置一个计时器和一个后台工作来读取日志文件,并在写入时将其内容打印到表单中的某个控件中。BackgroundWorker&Timer,仅读取日志文件的新行?

我不能使用FileSystemWatcher类,因为看起来有些破碎:有时事件“改变”会触发,有时不会。它具有极低的“汇集率”。

所以我创建了一个Timer和一个FileSystemWatcher。在计时器的“滴答”事件中,后台工作人员完成其工作。

现在的问题是:如何只读取自上次检查工作人员后添加的行?

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! 
} 

编辑:代码解决方案(也许还有一个更优雅的方式?):

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

回答

2

检查,并在每次读取日志的时间存储文件大小,然后开始你的文字阅读器(或任何你正在使用的)在你下次读的时候。

+0

我选择了你的方式,非常感谢。我编辑了第一篇文章以包含代码解决方案。 – gremo 2010-11-30 22:06:06

+0

非常感谢发布解决方案 – 2013-06-19 11:18:05

2

如果你只想在表单上查看你的日志文件,那么为什么不做一些简单的事情,比如编写你自己的Appender,它是由TextBox,RichTextBox或其他类型支持的。

这里有一些链接,我发现只是在做一个快速谷歌搜索“log4net的文本框添加器”:

http://www.nimblecoder.com/blog/archive/2009/01/30/using-a-delegate-and-custom-appender-with-log4net-to-display.aspx(这一个看起来很酷,因为它允许你指定一个委托在每个日志消息执行,所以你甚至不会被绑定到一个TextBox上,你可以根据你想要的日志输出去写不同的代理)。

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(这一个是提高对每个被记录的消息的事件的追加程序)。

http://markmail.org/message/ma62bdjpmab3cn7y(比较近 - 张贴在2008 - 使用RichTextBox中所产生ColoredConsoleAppender式输出)

http://www.claassen.net/geek/blog/2005/06/log4net-scrollingtextbox.html(这一个使用MemoryAppender捕捉到的日志信息,然后记下这些信息到文本框)

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

我还没有试过这些,所以我不能担保他们的质量。但是,我认为使用由TextBox支持的自定义Appender的方法似乎比试图观看日志文件,读取它然后将消息放入文本框中更好。

,我虽然简单看一看这些附加目的地发现一些共同的主题:

  1. 当你写从追加程序的文本框,你可能需要使用的BeginInvoke。

  2. 一个棘手的部分似乎是告诉Appender要写入哪个TextBox。在大多数情况下,Appender通过配置文件进行配置,然后以编程方式将文本框添加到Appender后,日志记录系统已初始化(我认为您必须检索至少一个记录器或记录至少一条消息以强制所有的延迟初始化发生)。

  3. 小心不断向文本框中添加行。您可能会耗尽大量内存,导致性能问题,或者超出TextBox的限制(如果有的话)。这些Appender中的几个包括定期从TextBox中删除“旧”行的代码。