У меня проблема с пользовательским log4netappender, рабочим фоном и текстовым полем wpf. Поле расширенного текста не обновляется правильно, когда я вхожу из фоновой темы.
Когда я вызываю регистратор из основного потока, текст корректно записывается в компонент пользовательского интерфейса (richtextbox). Но когда я вызываю регистратор из BackgroundWorker, возникает событие добавления регистратора, но пользовательский интерфейс (richtextbox) никогда не обновляется ... Почему это?
Спасибо за любую помощь!
Вот мой код основных окон, содержащих кнопку для запуска 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);
}
...}
Вот мой "WpfRichTextBoxAppender", пользовательский appender для 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();
}
}
}