C# 多线程 委托解决方案/winForm界面卡死
场景:在别的类中,调用主窗体的UI控件,报错信息:
线程间操作无效: 从不是创建控件“xxx”的线程访问它
主窗体:
C/C++ Code复制内容到剪贴板
- public partial class Form1 : Form
- {
- // 定义委托类型
- delegate void SetTextCallback(String str);
- private void EmployeeButton_Click(object sender, EventArgs e)
- {
- // 开启线程
- Thread th = new Thread(ThreadProcSafe);
- th.Start();
- }
- // 线程主体方法
- private void ThreadProcSafe()
- {
- // 创建对象
- SynchronizeDoor obj = new SynchronizeDoor
- {
- _form1 = this
- };
- obj.DoorEmployee(); // 同步人员数据
- }
- // 进入线程中插入日志说明
- public void InsertRichText(String str)
- {
- if (RichTextBox.InvokeRequired)
- {
- // 解决窗体关闭时出现“访问已释放句柄”异常
- while (RichTextBox.IsHandleCreated == false)
- {
- if (RichTextBox.Disposing || RichTextBox.IsDisposed) return;
- }
- SetTextCallback d = new SetTextCallback(InsertRichText); // 返回委托的类型
- RichTextBox.Invoke(d, new object[] { str });
- }
- else
- {
- RichTextBox.Text = RichTextBox.Text.Insert(0, DateTime.Now.ToString() + " - " + str + Environment.NewLine);
- }
- }
- private void Form1_FormClosed(object sender, FormClosedEventArgs e)
- {
- // 彻底的退出
- System.Environment.Exit(0);
- }
- }
- }
C/C++ Code复制内容到剪贴板
- class SynchronizeDoor
- {
- public Form1 _form1; // 将主窗口的form传递进来,可以调用其组件
- // 同步人员数据
- public void DoorEmployee()
- {
- for (int i = 0; i < 1000; i++)
- {
- if (i % 2 == 0)
- {
- _form1.InsertRichText("123456789");
- }
- else
- {
- _form1.InsertRichText("一二三四五六七八九");
- }
- Thread.Sleep(1000);
- }
新建一个richTextBox,多行文本框 ,命名:RecvRichTextBox
C# Code复制内容到剪贴板
- //线程内向文本框txtRecvMssg中添加字符串及委托
- private delegate void PrintRecvMssgDelegate(string s);
- private void PrintRecvMssg(string info)
- {
- RecvRichTextBox.Text += string.Format("[{0}]:{1}\r\n",
- DateTime.Now.ToLongTimeString(), info);
- }
使用时:
C# Code复制内容到剪贴板
- string data = "123444";
- Invoke(new PrintRecvMssgDelegate(PrintRecvMssg),
- new object[] { data });