[英]Log4net custom appender problem with dispatcher?
I have a problem with a custom log4netappender, a backgound worker and a wpf rich text box. 我对自定义log4netappender,背景工和wpf富文本框有疑问。 The rich text box is not updated correctly when I log from a backgound thread.
当我从backgound线程登录时,RTF文本框未正确更新。
When I call the logger from the main thread, the text is correctly logged to the UI component (the richtextbox). 当我从主线程调用记录器时,文本已正确记录到UI组件(richtextbox)中。 But when I call the logger from a BackgroundWorker, the logger Append event is raised but the UI (the richtextbox) is never updated... Why that ?
但是,当我从BackgroundWorker调用记录器时,会引发记录器Append事件,但是UI(richtextbox)从未更新过……为什么?
Thanks for any help ! 谢谢你的帮助 !
Here is my code of a main windows containing a button to launch backgroundworker and a custom control nammed "RichTraceBox" : 这是我的主窗口代码,其中包含一个用于启动backgroundworker的按钮和一个命名为“ RichTraceBox”的自定义控件:
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);
}
...}
Here is my "WpfRichTextBoxAppender", a custom appender for log4net that display messages on a custom control containing a wpf richTextBox: 这是我的“ WpfRichTextBoxAppender”,它是log4net的自定义附加程序,可在包含wpf richTextBox的自定义控件上显示消息:
/// <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();
}
}
}
I had the same problem and solved it with a Paragraph item, as so... 我遇到了同样的问题,并使用“段落”项解决了问题,因此...
_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);
I have not used WPF, so I can't really comment on why, specifically, this is not working as you expect it to. 我没有使用过WPF,因此我无法真正评论为什么,特别是为什么它不能如您期望的那样工作。 However, I did find this link to a blog posting where peteohanlon shows how to make a log4net Appender that redirects its output to a WPF text box.
但是,我确实找到了指向博客文章的链接,其中peteohanlon显示了如何制作log4net Appender并将其输出重定向到WPF文本框。 He specifically mentions using INotifyPropertyChanged.
他特别提到使用INotifyPropertyChanged。 Maybe something in his post will help you.
也许他的帖子中的内容会对您有所帮助。
Also, here is a link to another answer that I posted here on SO that links to several TextBox-based Appenders (I don't think any of them are WPF, unfortunately): 另外,这是指向我在SO上发布的另一个答案的链接,该答案指向多个基于TextBox的Appender(不幸的是,我认为它们都不是WPF):
BackgroundWorker & Timer, reading only new lines of a log file? BackgroundWorker&Timer,仅读取日志文件的新行吗?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.