I’ve a RichTextBox which I use as output from a custom TraceListener shown below:
The trouble is this seems to deadlock hard if anyone is writing debug/trace info from other
threads while a GUI dialog also is trying to write debug/trace info.
Anyone care to point at some obvious errors here ? :
class MyTraceListener : TraceListener
{
private RichTextBox output;
public MyTraceListener (RichTextBox output) {
this.Name = "DebugTrace";
this.output = output;
}
public override void Write(string message) {
Action append = delegate() { output.AppendText(message); };
if (output.InvokeRequired) {
IAsyncResult result = output.BeginInvoke(append);
output.EndInvoke(result);
} else {
append();
}
}
public override void WriteLine(string message) {
Action append = delegate() { output.AppendText(message + "\r\n"); };
if (output.InvokeRequired) {
IAsyncResult result = output.BeginInvoke(append);
output.EndInvoke(result);
} else {
append();
}
}
}
Here’s what’s likely happening:
waiting to execute the delegate in
the GUI thread.
System.Diagnostics.Trace.WriteLine
somewhere (afaik the trace system
employs locks to be thread safe.)
Calling just Invoke will likely not solve the problem, since Invoke blocks until the delegate is done running.
Calling only BeginInvoke should solve the locking, BeginInvoke will just initiate an asynchronous call to the GUI thread, not waiting till it’s finished thus leaving the trace system and unblock the GUI thread. (I’m not sure about the ramification of not calling EndInvoke though.