开发者社区> 非常老帅> 正文

在C#中子线程如何操作主线程中窗体上控件

简介:                                                        在C#中子线程如何操作主线程中窗体上控件         在C#中,直接在子线程中对窗体上的控件操作是会出现异常,这是由于子线程和运行窗体的线程是不同的空间,因此想要在子线程来操作窗体上的控件,是不可能简单的通过控件对象名来操作,但不是说不能进行操作,微软提供了Invoke的方法,其作用就是让子线程告诉窗体线程来完成相应的控件操作。
+关注继续查看

                                                       在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>
 24         public 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>
 35         private void frmMain_FormClosed(object sender, FormClosedEventArgs e)
 36         {
 37             if (ChaosThreadList.Count > 0)
 38             {
 39                 //编列自定义队列,将所有线程终止
 40                 foreach (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>
 54         private delegate void DispMSGDelegate(int index,string MSG);
 55 
 56         /// <summary>
 57         /// 定义一个函数,用于向窗体上的ListView控件添加内容
 58         /// </summary>
 59         /// <param name="iIndex"></param>
 60         /// <param name="strMsg"></param>
 61         private void DispMsg(int iIndex,string strMsg)
 62         {
 63             if (this.lstMain.InvokeRequired==false)                      //如果调用该函数的线程和控件lstMain位于同一个线程内
 64             {
 65                 //直接将内容添加到窗体的控件上
 66                 ListViewItem lvi = new ListViewItem();
 67                 lvi.SubItems[0].Text = iIndex.ToString();
 68                 lvi.SubItems.Add(strMsg);
 69                 this.lstMain.Items.Insert(0, lvi);
 70             }
 71             else                                                        //如果调用该函数的线程和控件lstMain不在同一个线程
 72             {
 73                 //通过使用Invoke的方法,让子线程告诉窗体线程来完成相应的控件操作
 74                 DispMSGDelegate DMSGD = new DispMSGDelegate(DispMsg);
 75 
 76                 //使用控件lstMain的Invoke方法执行DMSGD代理(其类型是DispMSGDelegate)
 77                 this.lstMain.Invoke(DMSGD, iIndex, strMsg);
 78                 
 79             }
 80         }
 81 
 82         /// <summary>
 83         /// 定义一个线程函数,用于循环向列表中添加数据
 84         /// </summary>
 85         private void Thread_DisplayMSG()
 86         {
 87             for (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>
101         private void btnBegin_Click(object sender, EventArgs e)
102         {
103             //创建一个新的线程
104             Thread tWorkingThread = new Thread(Thread_DisplayMSG);
105 
106             //将新建的线程加入到自定义线程队列中,以便在窗体结束时关闭所有的线程
107             ChaosThreadList.Add(tWorkingThread);
108 
109             //开启线程
110             tWorkingThread.Start();
111         }     
112 
113     }
114 } 

这样子就可以实现用子线程去操作主线程窗体上的控件的内容,同时,又不影响主线程对窗体上其他控件的响应。程序运行截图如下:

  

点击[开始]按钮,程序开启一个新的线程,不断向列表中添加新的数据,而同时不会影响主界面对其它控件(例如:文本框)的响应。

 

[P.S]:

INVOKE方法的作用:

它使该控件所在的线程执行Invoke方法参数中指定的代理,也就是使主线程执行我们想对控件进行的操作。


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
【Java 并发编程】线程操作原子性问题 ( 问题业务场景分析 | 使用 synchronized 解决线程原子性问题 )
【Java 并发编程】线程操作原子性问题 ( 问题业务场景分析 | 使用 synchronized 解决线程原子性问题 )
15 0
Java多线程--线程常用操作方法
<h1>1、取得和设置线程名称</h1> <div> <img src="http://img.blog.csdn.net/20131011094925062?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2FsZG1lcg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/
1331 0
【Java 并发编程】线程简介 ( 原子操作 | volatile 关键字使用场景 )
【Java 并发编程】线程简介 ( 原子操作 | volatile 关键字使用场景 )
13 0
操作系统的线程管理机制以及Thread.Sleep()的作用
说明:本文章内容来自某论坛里的一位大牛的回复。 引题:我们可能经常会用到 Thread.Sleep 函数来使线程挂起一段时间。
740 0
为什么有时候在子线程更新UI没报错?
为什么有时候在子线程更新UI没报错?
25 0
C#使用OleDB操作ACCESS插入数据时提示:参数 @p_Contract 没有默认值
C#使用OleDB操作ACCESS插入数据时提示:参数 @p_Contract 没有默认值 OleDbParameter param = new OleDbParameter("" + dc.ColumnName, dc.DataType); 出现该问题的原因是创建了Parameter,却没有为Parameter.value指定一个值。
893 0
更高效地提高redis client多线程操作的并发吞吐设计
Redis是一个非常高效的基于内存的NOSQL数据库,它提供非常高效的数据读写效能.在实际应用中往往是带宽和CLIENT库读写损耗过高导致无法更好地发挥出Redis更出色的能力.下面结合一些redis本身的特性和一些client操作上的改变来提高整个redis操作的交通.
958 0
AsyncHttpClient放在子线程执行时抛出异常的解决方法
AsyncHttpClient放在子线程执行时抛出异常的解决方法
75 0
+关注
非常老帅
IT行业从业10+年
481
文章
1
问答
文章排行榜
最热
最新
相关电子书
更多
OceanBase 入门到实战教程
立即下载
阿里云图数据库GDB,加速开启“图智”未来.ppt
立即下载
实时数仓Hologres技术实战一本通2.0版(下)
立即下载