首页 / C# / 在C#中子线程如何操作主线程中窗体上控件
在C#中子线程如何操作主线程中窗体上控件
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了在C#中子线程如何操作主线程中窗体上控件,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3477字,纯文字阅读大概需要5分钟。
内容图文
![在C#中子线程如何操作主线程中窗体上控件](/upload/InfoBanner/zyjiaocheng/1277/8aeabcb016f94e919e19668be44cd8b8.jpg)
在C#中子线程如何操作主线程中窗体上控件
在C#中,直接在子线程中对窗体上的控件操作是会出现异常,这是由于子线程和运行窗体的线程是不同的空间,因此想要在子线程来操作窗体上的控件,是不可能简单的通过控件对象名来操作,但不是说不能进行操作,微软提供了Invoke的方法,其作用就是让子线程告诉窗体线程来完成相应的控件操作。
要实现该功能,基本思路如下:
把想对另一线程中的控件实施的操作放到一个函数中,然后使用delegate代理那个函数,并且在那个函数中加入一个判断,用 InvokeRequired 来判断调用这个函数的线程是否和控件线程处于同一线程中,如果是则直接执行对控件的操作,否则利用该控件的Invoke或BeginInvoke方法来执行这个代理。示例代码如下:
1 using System; 2 using System.Collections.Generic; 3 using System.Windows.Forms; 4 5 using System.Threading; 6 7 namespace 子线程操作主线程窗体上的控件 8 { 9 public partial class frmMain : Form 10 { 11 /* ********************* 定义该类的私有成员 ************************* */ 12 13 /// <summary> 14 /// 定义一个队列,用于记录用户创建的线程 15 /// 以便在窗体关闭的时候关闭所有用于创建的线程 16 /// </summary> 17 private List<Thread> ChaosThreadList; 18 19/********************** 该类的初始化相关函数 ************************/ 20 21///<summary> 22/// 窗体的初始化函数,初始化线程队列ChaosThreadList 23///</summary> 24public frmMain() 25 { 26 InitializeComponent(); 27 ChaosThreadList = new List<Thread>(); 28 } 29 30///<summary> 31/// 窗体的关闭事件处理函数,在该事件中将之前创建的线程全部终止 32///</summary> 33///<param name="sender"></param> 34///<param name="e"></param> 35privatevoid frmMain_FormClosed(object sender, FormClosedEventArgs e) 36 { 37if (ChaosThreadList.Count > 0) 38 { 39//编列自定义队列,将所有线程终止 40foreach (Thread tWorkingThread in ChaosThreadList) 41 { 42 tWorkingThread.Abort(); 43 } 44 } 45 } 46 47/**************************** 定义该类的自定义函数 ***********************/ 48 49///<summary> 50/// 定义一个代理 51///</summary> 52///<param name="index"></param> 53///<param name="MSG"></param> 54privatedelegatevoid DispMSGDelegate(int index,string MSG); 55 56///<summary> 57/// 定义一个函数,用于向窗体上的ListView控件添加内容 58///</summary> 59///<param name="iIndex"></param> 60///<param name="strMsg"></param> 61privatevoid DispMsg(int iIndex,string strMsg) 62 { 63if (this.lstMain.InvokeRequired==false) //如果调用该函数的线程和控件lstMain位于同一个线程内 64 { 65//直接将内容添加到窗体的控件上 66 ListViewItem lvi = new ListViewItem(); 67 lvi.SubItems[0].Text = iIndex.ToString(); 68 lvi.SubItems.Add(strMsg); 69this.lstMain.Items.Insert(0, lvi); 70 } 71else//如果调用该函数的线程和控件lstMain不在同一个线程 72 { 73//通过使用Invoke的方法,让子线程告诉窗体线程来完成相应的控件操作 74 DispMSGDelegate DMSGD = new DispMSGDelegate(DispMsg); 75 76//使用控件lstMain的Invoke方法执行DMSGD代理(其类型是DispMSGDelegate) 77this.lstMain.Invoke(DMSGD, iIndex, strMsg); 78 79 } 80 } 81 82///<summary> 83/// 定义一个线程函数,用于循环向列表中添加数据 84///</summary> 85privatevoid Thread_DisplayMSG() 86 { 87for (int i = 0; i < 10000; i++) 88 { 89 DispMsg(i + 1, "Welcome you : " + (i + 1).ToString()); 90 Thread.Sleep(10); 91 } 92 } 93 94/******************************* 定义该类的事件处理函数 ********************************/ 95 96///<summary> 97/// 【开始】按钮的单击事件处理函数,新建一个线程向窗体上的ListView控件填写内容 98///</summary> 99///<param name="sender"></param>100///<param name="e"></param>101privatevoid btnBegin_Click(object sender, EventArgs e) 102 { 103//创建一个新的线程104 Thread tWorkingThread = new Thread(Thread_DisplayMSG); 105106//将新建的线程加入到自定义线程队列中,以便在窗体结束时关闭所有的线程107 ChaosThreadList.Add(tWorkingThread); 108109//开启线程110 tWorkingThread.Start(); 111 } 112113 } 114 }
这样子就可以实现用子线程去操作主线程窗体上的控件的内容,同时,又不影响主线程对窗体上其他控件的响应。程序运行截图如下:
点击[开始]按钮,程序开启一个新的线程,不断向列表中添加新的数据,而同时不会影响主界面对其它控件(例如:文本框)的响应。
[P.S]:
INVOKE方法的作用:
它使该控件所在的线程执行Invoke方法参数中指定的代理,也就是使主线程执行我们想对控件进行的操作。
原文:http://blog.csdn.net/shuaihj/article/details/41316909
内容总结
以上是互联网集市为您收集整理的在C#中子线程如何操作主线程中窗体上控件全部内容,希望文章能够帮你解决在C#中子线程如何操作主线程中窗体上控件所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。