在不加任何修饰的情况下,C# 默认不允许跨线程访问控件,实际在项目开发过程中,经常使用跨线程操作控件属性,需要设置相关属性才能正确使用,两种方法设置如下:
方法1:告诉编译器取消跨线程访问检查,在窗体构造函数中编写,如下图所示:
方法2:创建一个异步委托并在UI线程上同步执行,来更新UI控件的文本内容
// 使用BeginInvoke异步更新,避免阻塞调用线程 if (richTextBox1.InvokeRequired) { richTextBox1.BeginInvoke(new Action(() => { richTextBox1.TabStop = false; richTextBox1.SelectedText = string.Empty; richTextBox1.SelectionFont = new Font(richTextBox1.SelectionFont, FontStyle.Bold); richTextBox1.SelectionColor = mLogMsgTypeColor[(int)msgtype]; richTextBox1.AppendText(string.Format("{0} =>{1} \n", msg, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))); richTextBox1.ScrollToCaret(); })); } else { richTextBox1.TabStop = false; richTextBox1.SelectedText = string.Empty; richTextBox1.SelectionFont = new Font(richTextBox1.SelectionFont, FontStyle.Bold); richTextBox1.SelectionColor = mLogMsgTypeColor[(int)msgtype]; richTextBox1.AppendText(string.Format("{0} =>{1} \n", msg, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))); richTextBox1.ScrollToCaret(); }二、关于BeginInvoke(异步委托) 和Invoke(同步委托)区别
Invoke = 同步执行 → 会等 UI 干完活,才继续往下走 → 可能卡死、死锁
BeginInvoke = 异步执行 → 丢给 UI 就走,不等待 → 不卡死、不死锁,安全高效不卡顿
标准写法:
if (control.InvokeRequired) { control.BeginInvoke(new Action(() => { // 这里操作 UI 控件 })); }