4 c#
我有一个方法,用于在表单中的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();
}
}
Run Code Online (Sandbox Code Playgroud)
当我从一个线程内运行的另一个方法调用LogEventText()时出现问题:
Thread thListening = new Thread(new ThreadStart(StartListening));
thListening.Start();
Run Code Online (Sandbox Code Playgroud)
在StartListening方法内部(它是一个创建的线程,处理为小型http服务器的主侦听套接字上的客户端创建的新tcp套接字),我使用LogTextEvent来记录一些数据,但是我收到InvalidOperationException是未处理的错误在第二行的LogTextEvent方法中,TextEventLog.SelectionStart = TextEventLog.Text.Length;
错误读取,跨线程操作无效:控制'rchEventLog'从其创建的线程以外的线程访问.
任何人都可以帮助分解正在发生的事情,为什么以及如何修复错误?
Dan*_*ted 10
尝试这样的事情:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
如果从富文本框的UI线程以外的线程调用LogTextEvent方法,它将向UI线程发布消息,这将导致在该线程中调用LogTextEvent方法.
通过使用BeginInvoke而不是Invoke,它是异步发布的,这意味着它会立即返回给调用者,而不是等待在另一个线程上执行该方法.对于像这样的日志记录方案,这可能是您想要的.如果您需要从控件或其他东西获取值,则可能需要使用Invoke.