C#报错"线程间操作无效: 从不是创建控件“XXX”的线程访问它"--解决示例
C# Winform程序中,使用线程对界面进行更新需要特殊处理,否则会出现异常“线程间操作无效: 从不是创建控件“taskView”的线程访问它。”
在网文“http://www.cnblogs.com/smileberry/p/3912918.html”的知道下,我做了下面的例程,希望对大家有所帮助,如果注释不够的话请访问原文。
例程是点击按钮后启动线程更新一个标签的文字,界面如下:
程序如下:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Threading; namespace ThreadCgGui { public partial class Form1 : Form { // 定义委托类型 delegate void SetTextCallback(String str); public Form1() { InitializeComponent(); } // 点击按钮启动线程 private void button1_Click(object sender, EventArgs e) { Thread th = new Thread(threadProcSafe); th.Start(); } // 线程主体方法 private void threadProcSafe() { for (int i = 0; i < 1000; i++) { if (i % 2 == 0) { this.setText("123456789"); } else { this.setText("一二三四五六七八九"); } Thread.Sleep(1000); } } // 本方法是跨线程更新UI使用的主流方法,使用控件的Invoke/BeginInvoke方法,将委托转到UI线程上调用,实现线程安全的更新 // 本质上还是把线程中要提交的消息,通过控制句柄调用委托交到UI线程中处理 public void setText(String str) { if (label1.InvokeRequired) { // 解决窗体关闭时出现“访问已释放句柄”异常 while (label1.IsHandleCreated == false) { if (label1.Disposing || label1.IsDisposed) return; } SetTextCallback d = new SetTextCallback(setText); label1.Invoke(d, new object[] { str }); } else { label1.Text = str; } } private void Form1_FormClosed(object sender, FormClosedEventArgs e) { // 彻底的退出 System.Environment.Exit(0); } } }
例程下载:
https://files.cnblogs.com/files/xiandedanteng/ThreadCgGui20170626.zip
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)