C#创建子线程,子线程使用委托更新控件
一、背景
由于在窗体程序中通过点击一个button
按键后需要更新TreeView
控件的内容,由于等待时间比较长,主程序无法一起在那边等待,需要去处理其它的事情,所以就需要创建新的子线程来处理。因为主线程主要用于窗体程序的更新,但子线程又存在问题是C#中禁止跨线程直接访问控件
,所以子线程中要更新窗体程序的控件要使用委托主线程来处理更新控件。
二、程序分析
using System.Threading; //声明线程命名空间
private void Updatebutton_Click(object sender, EventArgs e) //按键控件处理程序
{
Thread SearchDevice = new Thread(FindCanDevice); //子线程的创建
if (update_flag ==false) //开始更新网络设备
{
update_flag =true;
UpdateprogressBar.Maximum= 127; //总共会查询126个设备
DevicetreeView.Nodes.Clear(); //快速清空TreeView的内容
NodeList = new TreeNode("Device List", 0, 0);
this.DevicetreeView.Nodes.Add(NodeList); //加入根节点
//Thread SearchDevice = new Thread(FindCanDevice);
SearchDevice.IsBackground = true; //当主线程关闭时,子线程也随着关闭
SearchDevice.Start(); //子线程启动
}
else //停止更新网络设备
{
update_flag = false;
}
}
private void FindCanDevice() //子线程处理程序
{
int ret; //寻找设备的状态
int countnum = 0;
for (int j = 1; j < 128; j++)
{
if (!update_flag) //退出网络设备的更新
break;
countnum++;
ret = GloableVar.WzCanOpenUpdateNetwork(j);
ShowDevice(ret, j, countnum);
}
}
public delegate void aa(int flagSuccess, int data, int count); //委托类型的说明
private void ShowDevice(int flagSuccess, int data, int count)
{
if(this.InvokeRequired) //判断是不是控件所在线程调用的,不是的话为true,Invoke用于跨线程调用控件进行操作
{
aa a = new aa(ShowDevice); //定义委托的函数
this.Invoke(a, new object[] { flagSuccess, data, count }); //指定用主线程中的控件去调用这个委托,相当于主线程来执行这个函数
}
else
{
if(flagSuccess== 0)
{
TreeNode NodeDevice = new TreeNode("Node ID " + data.ToString());
NodeList.Nodes.Add(NodeDevice); //加入子节点
DevicetreeView.ExpandAll(); //展开所有的节点
}
UpdateprogressBar.Value = count;
}
}
1、 Thread SearchDevice = new Thread(FindCanDevice)
为新建的子线程,子线程的处理函数为void FindCanDevice()
,完成线程创建后需要启动线程 SearchDevice.Start()
,线程才会运行。
2、在进入子线程处理函数后,如果因为控件是主线程创建的,子线程不是控件所在的线程调用,所以this.InvokeRequired
一直为true
,进入判断程序后通过this.Invoke
将子线程的处理委托给主线程去处理,由于委托的函数为ShowDevice
并且当前调用执行的线程为控件所在的主线程调用,这时又判断this.InvokeRequired
为false
,所以执行控件的更新处理
if(flagSuccess== 0)
{
TreeNode NodeDevice = new TreeNode("Node ID " + data.ToString());
NodeList.Nodes.Add(NodeDevice); //加入子节点
DevicetreeView.ExpandAll(); //展开所有的节点
}
UpdateprogressBar.Value = count;
三、参考文档
http://www.cnblogs.com/miniwiki/archive/2010/06/18/1760540.html //线程的创建
http://www.cnblogs.com/songxingzhu/p/3677307.html //InvokeRequired和Invoke的使用
by 羊羊得亿
2017-07-04 ShenZhen
C#创建子线程,子线程使用委托更新控件的更多相关文章
- [转]MFC子线程中更新控件内容的两种办法
一.概述 每个系统中都有线程(至少都有一个主线程),而线程最重要的作用就是并行处理,提高软件的并发率.针对界面来说,还能提高界面的响应能力.一般的,为了应用的稳定性,在数据处理等耗时操作会单独在一个线 ...
- Winfrom 如何安全简单的跨线程更新控件
来源:http://www.cnblogs.com/rainbowzc/archive/2010/09/29/1838788.html 由于多线程可能导致对控件访问的不一致,导致出现问题.C#中默认是 ...
- C# 线程调用主线程中的控件
由于项目的需要,最近几天一直在做串口和数据库.由于C#使用的时间不长,所以在编写代码和调试的过程中总是遇到意想不到的问题,比如在使用串口接收数据的时候,在接收数据事件中想把接收的数据放入一个textb ...
- C# 通过委托控制进度条以及多线程更新控件
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- QT 创建一个具有复选功能的下拉列表控件
最近研究了好多东西,前两天突然想做一个具有复选功能的下拉列表框.然后在网上"学习"了很久之后,终于发现了一个可以用的,特地发出来记录一下. 一.第一步肯定是先创建一个PROJECT ...
- VB.NET章鱼哥出品—怎样解决MDI子窗口被父窗口中的控件覆盖的问题
近期有个网友问我这个问题,我就上网搜了下,结果非常失望.有几个在CSDN上发的求助帖.看到最后都没有找到明白的答案. 这里笔者在网上找到了API函数SetParent(),并对网上的错误进行了改动,并 ...
- AE二次开发,解决子窗体使用父窗体的AxControl控件
在子窗体写构造函数,然后再在父窗体按钮点击事件下写 public frmIDW(AxMapControl axMapControl1) { InitializeComponent(); this.ax ...
- iOS代码实现:创建按钮,绑定按钮事件,读取控件值
// // main.m // Hello // // Created by lishujun on 14-8-28. // Copyright (c) 2014年 lishujun. All rig ...
- C#子线程更新UI控件的方法总结
http://blog.csdn.net/jqncc/article/details/16342121 在winform C/S程序中经常会在子线程中更新控件的情况,桌面程序UI线程是主线程,当试图从 ...
随机推荐
- D3.js 整体展示篇
近期一段时间研究社会成员网络关系图的一些可视化展示,对大数据可视化这片荒漠一筹莫展的自己,幸好发现了D3这片充满活力的绿洲.我决定在这块宝地贪婪地大餐一番. 本文介绍主要来自官网翻译及用户使用后感想资 ...
- hdoj--3123--GCC(技巧阶乘取余)
GCC Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Total Subm ...
- poj--3281-- DiningI(最大流)
Dining Time Limit: 2000MS Memory Limit: 65536KB 64bit IO Format: %I64d & %I64u Submit Status ...
- 分布式架构中shiro
分布式架构中shiro 前言:前段时间在搭建公司游戏框架安全验证的时候,就想到之前web最火的shiro框架,虽然后面实践发现在netty中不太适用,最后自己模仿shiro写了一个缩减版的,但是中间花 ...
- hashCode 和 equals 方法
hashCode 和 equals 方法 hashCode()和equals()定义在Object类中,这个类是所有java类的基类,所以所有的java类都继承这两个方法. 使用hashCode()和 ...
- 开发板ping得通本地,但是不能上网
在3531D的开发板上面接入LAN7500的USB转以太网口,加载完驱动后. 然后开启eth1 查看一下ifconfig,发现没有ip,配置一下ip 直接ping本地发现可以ping得通,代表链路是连 ...
- Linux运维管理的必备工具
一.统一账号管理 1.LDAP 统一管理各种平台帐号和密码,包括但不限于各种操作系统(Windows.Linux),Linux系统sudo集成,系统用户分组,主机登入限制等:可与Apache,HTTP ...
- OpenJDK源码研究笔记(十一):浅析Javac编译过程中的抽象语法树(IfElse,While,Switch等语句的抽象和封装)
浅析OpenJDK源码编译器Javac的语法树包com.sun.source.tree. 抽象语法树,是编译原理中的经典问题,有点难,本文只是随便写写. 0.赋值语句 public interface ...
- 【Codeforces Round #425 (Div. 2) A】Sasha and Sticks
[Link]: [Description] [Solution] 傻逼题; 获取n/k; 对n/k的奇偶性讨论一下就好 [NumberOf WA] 0 [Reviw] [Code] #include ...
- CodeForcesGym 100502D Dice Game
Dice Game Time Limit: 1000ms Memory Limit: 524288KB This problem will be judged on CodeForcesGym. Or ...