我创建了一个事件驱动的记录器,当从另一个线程调用时它似乎有问题。我怎样才能使它线程安全?
这是记录器类:
public static class MyLogger
{
private static List<string> log = new List<string>();
public static event EventHandler LogAdded;
private static string indent = "";
public static void Log(string message)
{
log.Add(indent + message);
if (LogAdded != null)
LogAdded(null, EventArgs.Empty);
}
}
在我的表单类中,我通过以下两种方式启动它:
public frm_main()
{
InitializeComponent();
MyLogger.LogAdded += new EventHandler(MyLogger_LogAdded);
}
这是发生崩溃的事件进度:
private void MyLogger_LogAdded(object sender, EventArgs e)
{
int length = rtb_logger.TextLength; // at end of text
string prefix = string.Format("{0:d3}: ", ++logindex);
string ToAppend = prefix + MyLogger.GetLastLog();
rtb_logger.AppendText(ToAppend);
if (ToAppend.Contains("Alert -"))
{
rtb_logger.SelectionStart = length;
rtb_logger.SelectionLength = ToAppend.Length;
rtb_logger.SelectionColor = Color.Red;
}
rtb_logger.AppendText(Environment.NewLine);
rtb_logger.SelectionStart = rtb_logger.TextLength;
rtb_logger.ScrollToCaret();
EnableControls();
}
在后台工作人员的以下调用中,崩溃发生在上面注释为“文本末尾”的第一行:
MyLogger.Log("Sending cmd: \"" + strCmdText + "\" to CMD.exe.");
如何使 MyLogger 类线程安全?
编辑:使用 SeeSharp 解决方案,代码更改为:
private void MyLogger_LogAdded(object sender, EventArgs e)
{
if (rtb_logger.InvokeRequired)
{
rtb_logger.BeginInvoke(new Action(delegate {
MyLogger_LogAdded(sender, e);
}));
return;
}
int length = rtb_logger.TextLength; // at end of text
string prefix = string.Format("{0:d3}: ", ++logindex);
string ToAppend = prefix + MyLogger.GetLastLog();
rtb_logger.AppendText(ToAppend);
if (ToAppend.Contains("Alert -"))
{
rtb_logger.SelectionStart = length;
rtb_logger.SelectionLength = ToAppend.Length;
rtb_logger.SelectionColor = Color.Red;
}
rtb_logger.AppendText(Environment.NewLine);
rtb_logger.SelectionStart = rtb_logger.TextLength;
rtb_logger.ScrollToCaret();
EnableControls();
}