在开发多线程应用程序时,跟踪调试信息对于理解程序的运行状态和调试问题至关重要。然而,直接在用户界面(UI)上显示跟踪信息可能会遇到线程安全问题。本文将介绍一个名为TextBoxTraceListener的类,它允许在多线程应用程序中安全地将跟踪信息输出到文本框中。
在为服务编写测试框架时,本以为会有人已经发布了一个TextBoxTraceListener类,这样就可以节省五分钟的时间。但不幸的是,Google搜索并没有找到合适的结果。看到的示例都不是线程安全的,并且需要所有的代码都在WindowsUI线程上执行——这在运行服务测试框架时并不是一个理想的解决方案。因此,决定自己编写一个,并将其分享出来供他人重用。这个类非常简单,主要是为了节省大家一些时间。
只需将TextBoxTraceListener类添加到代码中,然后创建一个监听器实例(在构造函数中传入想要输出跟踪信息的文本框),然后将跟踪监听器添加到Trace或Debug。示例测试框架应该能给一个很好的使用示例,但可能看起来像这样(其中txtDisplayTrace是表单上的一个文本框):
public partial class Form1 : Form
{
TextBoxTraceListener _textBoxListener;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
_textBoxListener = new TextBoxTraceListener(txtDisplayTrace);
Trace.Listeners.Add(_textBoxListener);
}
}
public class TextBoxTraceListener : TraceListener
{
private TextBox _target;
private StringSendDelegate _invokeWrite;
public TextBoxTraceListener(TextBox target)
{
_target = target;
_invokeWrite = new StringSendDelegate(SendString);
}
public override void Write(string message)
{
_target.Invoke(_invokeWrite, new object[] { message });
}
public override void WriteLine(string message)
{
_target.Invoke(_invokeWrite, new object[] { message + Environment.NewLine });
}
private delegate void StringSendDelegate(string message);
private void SendString(string message)
{
// No need to lock text box as this function will only
// ever be executed from the UI thread
_target.Text += message;
}
}