2010-12-13 6 views
1

カスタムlog4netappender、backgoundワーカー、およびwpfリッチテキストボックスに問題があります。バックグラウンドスレッドからログオンすると、リッチテキストボックスが正しく更新されません。ディスパッチャにLog4netカスタムアペンダーの問題がありますか?

メインスレッドからロガーを呼び出すと、テキストはUIコンポーネント(richtextbox)に正しく記録されます。しかし、私がBackgroundWorkerからロガーを呼び出すと、ロガーのAppendイベントは発生しますが、UI(richtextbox)は決して更新されません...なぜですか?

ありがとうございました!ここで

はBackgroundWorkerのと「RichTraceBox」nammedカスタムコントロールを起動するボタンを含むメインウィンドウの私のコードです:ここでは

 private static readonly log4net.ILog _logger = log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 

    TraceBox TheTraceBox; 

    public MainPanel() 
    { 
     InitializeComponent(); 

     // Configure Log4Net 
     Hierarchy hierarchy = (Hierarchy)LogManager.GetRepository(); 
     hierarchy.Root.RemoveAllAppenders(); /*Remove any other appenders*/   
     //// .... create and configure appender .../// 
     WpfRichTextBoxAppender notify = new WpfRichTextBoxAppender(this.TheTraceBox); 
     PatternLayout layout = new PatternLayout(); 
     layout.ConversionPattern = "%d [%t] %-5p %c %m%n"; 
     notify.Layout = layout; 
     notify.ActivateOptions(); 


     log4net.Config.BasicConfigurator.Configure(notify); 
     _logger.Debug("Correctly logged"); 

     } 

private void button1_Click(object sender, RoutedEventArgs e) 
    { 
     BackgroundWorker checkGraphlongWorker = new BackgroundWorker(); 
     checkGraphlongWorker.DoWork += new DoWorkEventHandler(checkGraphlongWorker_DoWork); 
     checkGraphlongWorker.RunWorkerAsync(); 

    } 

    void checkGraphlongWorker_DoWork(object sender, DoWorkEventArgs e) 
    { 
     Thread.Sleep(2000); 
     _logger.Debug("This is never Logged...."); 

     this.TheTraceBox.DisplayOnTraceBox("...But this is corectly displayed ???!!", Brushes.Red); 


     } 
...} 

は私の「WpfRichTextBoxAppender」、上のメッセージを表示するlog4netのためのカスタムアペンダですWPFのリッチテキストボックスを含むカスタムコントロール:

/// <summary> 
/// Description of RichTextBoxAppender. 
/// </summary> 
public class WpfRichTextBoxAppender : AppenderSkeleton 
{ 
    #region Private Instance Fields 
    private TraceBox richTextBox = null; 
    private int maxTextLength = 100000; 
    #endregion 

    private delegate void UpdateControlDelegate(LoggingEvent loggingEvent); 

    #region Constructor 
    public WpfRichTextBoxAppender(TraceBox myRichTextBox) 
     : base() 
    { 
     richTextBox = myRichTextBox; 
    } 
    #endregion 


    protected override void Append(LoggingEvent[] loggingEvents) 
    { 
     base.Append(loggingEvents); 
    } 

    protected override void Append(LoggingEvent loggingEvent) 
    { 

     if (richTextBox != null) 
     { 
      // There may be performance issues if the buffer gets too long 
      // So periodically clear the buffer 
      if (richTextBox.TextLenght > maxTextLength) 
      { 
       richTextBox.ClearTrace(); 
      } 
      Brush color = Brushes.Black; 
      if (loggingEvent.Level == Level.Alert) 
       color = Brushes.Orange; 
      else if (loggingEvent.Level == Level.Critical) 
       color = Brushes.DarkOrange; 
      else if (loggingEvent.Level == Level.Error) 
       color = Brushes.Red; 
      else if (loggingEvent.Level == Level.Fatal) 
       color = Brushes.Red; 
      else if (loggingEvent.Level == Level.Warn) 
       color = Brushes.OrangeRed; 
      this.richTextBox.DisplayOnTraceBox(RenderLoggingEvent(loggingEvent), color); 
     } 
    } 
} 


public partial class TraceBox : UserControl 
{ 
    public TraceBox() 
    { 
     InitializeComponent(); 
     this.Visibility = System.Windows.Visibility.Visible; 
    }   

    private void Button_Clear_Click(object sender, RoutedEventArgs e) 
    { 
     this.ClearTrace(); 
     //this.Output.Text = ""; 
    } 


    public void ClearTrace() 
    { 
     FlowDocument myFlowDoc = new FlowDocument(); 
     this.ConsoleOutputTextBox.Document = myFlowDoc; 
    } 


    public int TextLenght { 
     get 
     { 
      TextRange tr = new TextRange(this.ConsoleOutputTextBox.Document.ContentStart, this.ConsoleOutputTextBox.Document.ContentEnd); 
      return tr.Text.Length; 
     } 
    } 

    private delegate void DisplayOnTraceBoxDel(object message, Brush messageColor); 
    public void DisplayOnTraceBox(object message, Brush messageColor) 
    {    
     if (!this.ConsoleOutputTextBox.Dispatcher.CheckAccess()) 
     { 
      this.ConsoleOutputTextBox.Dispatcher.Invoke(new DisplayOnTraceBoxDel(DisplayOnTraceBox), DispatcherPriority.DataBind, new object[] { message, messageColor }); 
     } 
     else 
     { 
      TextRange tr = new TextRange(this.ConsoleOutputTextBox.Document.ContentEnd, this.ConsoleOutputTextBox.Document.ContentEnd); 
      tr.Text = message.ToString(); 
      tr.ApplyPropertyValue(TextElement.FontFamilyProperty, "Consolas"); 
      tr.ApplyPropertyValue(TextElement.FontSizeProperty, 10D); 
      tr.ApplyPropertyValue(Paragraph.MarginProperty, new Thickness(0)); 
      //tr.ApplyPropertyValue(Paragraph.BackgroundProperty, "LightSteelBlue"); 
      tr.ApplyPropertyValue(TextElement.ForegroundProperty, messageColor); 
      this.ConsoleOutputTextBox.UpdateLayout(); 
     } 
    } 


} 

答えて

0

私はWPFを使用していないので、私は本当にあなたはそれが期待どおりなぜ、具体的には、これが動作していないにコメントすることはできません。しかし、私はこれを見つけましたlink to a blog postingpeteohanlonは、出力をWPFテキストボックスにリダイレクトするlog4net Appenderを作る方法を示しています。彼は特にINotifyPropertyChangedの使用について言及しています。彼のポストの何かがあなたを助けるだろう。

BackgroundWorker & Timer, reading only new lines of a log file?

0
:また

は、ここでいくつかのTextBoxベースのアペンダにリンクして、私はSOにここに掲載別の答えへのリンク(私は残念ながら、それらのいずれかが、WPFとは思わない)であります

私は同じ問題を抱えていたので、段落項目で解決しました...

  _textBox.Dispatcher.BeginInvoke(new Action<string>(s => 
      {  
       Paragraph p = new Paragraph(); 
       p.Inlines.Add(new Run(s) { Foreground = Brushes.Red }); 
       ((RichTextBox)_textBox).Document.Blocks.Add(p); 
      }), msg); 
関連する問題