我有一个方法,用于在表单中的RichTextBox上显示输出.
public void LogTextEvent(RichTextBox TextEventLog, Color TextColor, string EventText) { string nDateTime = DateTime.Now.ToString("hh:mm:ss tt") + " - "; // color text. TextEventLog.SelectionStart = TextEventLog.Text.Length; TextEventLog.SelectionColor = TextColor; // newline if first line, append if else. if (TextEventLog.Lines.Length == 0) { TextEventLog.AppendText(nDateTime + EventText); TextEventLog.ScrollToCaret(); TextEventLog.AppendText(System.Environment.NewLine); } else { TextEventLog.AppendText(nDateTime + EventText + System.Environment.NewLine); TextEventLog.ScrollToCaret(); } }
当我从一个线程内运行的另一个方法调用LogEventText()时出现问题:
Thread thListening = new Thread(new ThreadStart(StartListening)); thListening.Start();
在StartListening方法内部(它是一个创建的线程,处理为小型http服务器的主侦听套接字上的客户端创建的新tcp套接字),我使用LogTextEvent来记录一些数据,但是我收到InvalidOperationException是未处理的错误在第二行的LogTextEvent方法中,TextEventLog.SelectionStart = TextEventLog.Text.Length;
错误读取,跨线程操作无效:控制'rchEventLog'从其创建的线程以外的线程访问.
任何人都可以帮助分解正在发生的事情,为什么以及如何修复错误?
尝试这样的事情:
public void LogTextEvent(RichTextBox TextEventLog, Color TextColor, string EventText) { if (TextEventLog.InvokeRequired) { TextEventLog.BeginInvoke(new Action(delegate { LogTextEvent(TextEventLog, TextColor, EventText); })); return; } string nDateTime = DateTime.Now.ToString("hh:mm:ss tt") + " - "; // color text. TextEventLog.SelectionStart = TextEventLog.Text.Length; TextEventLog.SelectionColor = TextColor; // newline if first line, append if else. if (TextEventLog.Lines.Length == 0) { TextEventLog.AppendText(nDateTime + EventText); TextEventLog.ScrollToCaret(); TextEventLog.AppendText(System.Environment.NewLine); } else { TextEventLog.AppendText(nDateTime + EventText + System.Environment.NewLine); TextEventLog.ScrollToCaret(); } }
如果从富文本框的UI线程以外的线程调用LogTextEvent方法,它将向UI线程发布消息,这将导致在该线程中调用LogTextEvent方法.
通过使用BeginInvoke而不是Invoke,它是异步发布的,这意味着它会立即返回给调用者,而不是等待在另一个线程上执行该方法.对于像这样的日志记录方案,这可能是您想要的.如果您需要从控件或其他东西获取值,则可能需要使用Invoke.