2010-11-30 8 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! 
} 

EDIT:コードソリューション(多分もっとエレガントな方法はありますか?):

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

+0

ありがとうたくさんのソリューションを投稿してください –

2

ストリームから読み取られた最後の文字のインデックスを追跡し、その後にその位置にseekを記録することができます。

編集:例はhttp://dotnetperls.com/seekを参照してください。

2

あなたが書いているようにフォームにログファイルを表示するだけであれば、TextBox、RichTextBoxなどに裏付けされた独自のAppenderを書くような簡単なことはできません。ここで

私はちょうど「log4netのテキストボックスのアペンダ」のための迅速なGoogle検索を行ったいくつかのリンクです:

http://www.nimblecoder.com/blog/archive/2009/01/30/using-a-delegate-and-custom-appender-with-log4net-to-display.aspxは、(それがすべてのログメッセージに実行するためのデリゲートを指定することができますので、この1つはかなりクールに見えます、あなたはTextBoxに縛られることさえありません。ログ出力をどこにするかによって、異なる代理人を書くことができます)。

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://www.l4ndash.com/Log4NetMailArchive%2Ftabid%2F70%2Fforumid%2F1%2Fpostid%2F15133%2Fview%2Ftopic%2FDefault.aspxは(この1つはログに記録されるすべてのメッセージのためのイベントを発生させアペンダです)。

http://markmail.org/message/ma62bdjpmab3cn7y(比較的最近 - 2008年に掲載 - 生成されたColoredConsoleAppenderスタイルの出力にリッチテキストボックスを使用しています)

http://www.claassen.net/geek/blog/2005/06/log4net-scrollingtextbox.html(この1つは、ログメッセージをキャプチャするためにMemoryAppenderを使用して、テキストボックスにそれらのメッセージを書き込みます)

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

私はこれらを試していないので、その品質を保証することはできません。しかし、私は、TextBoxに裏打ちされたカスタムアペンダーを使用するアプローチは、ログファイルを見て、それを読んでからTextBoxにメッセージを置くよりもはるかに良いアプローチのように思えます。

これらのアペンダ上で簡単に見ながら、私は気づいたいくつかの共通のテーマ:

  1. あなたがアペンダからのTextBoxに書き込むとき、あなたはBeginInvokeメソッドを使用する必要があります。

  2. 1つのトリッキーな部分は、どのTextBoxに書き込むかをAppenderに伝えるようです。ほとんどの場合、Appenderはconfigファイルを介して設定され、TextBoxはAppenderにプログラムによって追加された後にロギングシステムが初期化されます(少なくとも1つのロガーを取得するか、怠惰な初期化が起こる)。

  3. TextBoxに常に行を追加するように注意してください。多くのメモリを使い果たしたり、パフォーマンス上の問題を引き起こしたり、TextBoxの制限を超える可能性があります(存在する場合)。これらのAppenderには、TextBoxから「古い」行を定期的に削除するコードが含まれています。

+0

うわー。私はlog4netがテキストファイルにクラップを書き込むという単純な作業をどれだけ複雑にしているか忘れていました。 :) – MusiGenesis