一、背景

由于在窗体程序中通过点击一个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.InvokeRequiredfalse,所以执行控件的更新处理

                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#创建子线程,子线程使用委托更新控件的更多相关文章

  1. [转]MFC子线程中更新控件内容的两种办法

    一.概述 每个系统中都有线程(至少都有一个主线程),而线程最重要的作用就是并行处理,提高软件的并发率.针对界面来说,还能提高界面的响应能力.一般的,为了应用的稳定性,在数据处理等耗时操作会单独在一个线 ...

  2. Winfrom 如何安全简单的跨线程更新控件

    来源:http://www.cnblogs.com/rainbowzc/archive/2010/09/29/1838788.html 由于多线程可能导致对控件访问的不一致,导致出现问题.C#中默认是 ...

  3. C# 线程调用主线程中的控件

    由于项目的需要,最近几天一直在做串口和数据库.由于C#使用的时间不长,所以在编写代码和调试的过程中总是遇到意想不到的问题,比如在使用串口接收数据的时候,在接收数据事件中想把接收的数据放入一个textb ...

  4. C# 通过委托控制进度条以及多线程更新控件

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  5. QT 创建一个具有复选功能的下拉列表控件

    最近研究了好多东西,前两天突然想做一个具有复选功能的下拉列表框.然后在网上"学习"了很久之后,终于发现了一个可以用的,特地发出来记录一下. 一.第一步肯定是先创建一个PROJECT ...

  6. VB.NET章鱼哥出品—怎样解决MDI子窗口被父窗口中的控件覆盖的问题

    近期有个网友问我这个问题,我就上网搜了下,结果非常失望.有几个在CSDN上发的求助帖.看到最后都没有找到明白的答案. 这里笔者在网上找到了API函数SetParent(),并对网上的错误进行了改动,并 ...

  7. AE二次开发,解决子窗体使用父窗体的AxControl控件

    在子窗体写构造函数,然后再在父窗体按钮点击事件下写 public frmIDW(AxMapControl axMapControl1) { InitializeComponent(); this.ax ...

  8. iOS代码实现:创建按钮,绑定按钮事件,读取控件值

    // // main.m // Hello // // Created by lishujun on 14-8-28. // Copyright (c) 2014年 lishujun. All rig ...

  9. C#子线程更新UI控件的方法总结

    http://blog.csdn.net/jqncc/article/details/16342121 在winform C/S程序中经常会在子线程中更新控件的情况,桌面程序UI线程是主线程,当试图从 ...

随机推荐

  1. HBase源代码分析之HRegion上MemStore的flsuh流程(二)

    继上篇<HBase源代码分析之HRegion上MemStore的flsuh流程(一)>之后.我们继续分析下HRegion上MemStore flush的核心方法internalFlushc ...

  2. vue16 自定义键盘属性

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. 20. idea刷新项目、清除项目缓存

    转自:https://www.cnblogs.com/suiyisuixing/p/7723458.html 点击File -> Invalidate caches ,点击之后在弹出框中点击确认 ...

  4. Unity(IoC)

    一.什么是IoC? IoC(Inversion of Control,控制反转)又称“依赖注入”(Dependence Injection,DI). 控制反转就是创建对象的权利由开发人员控制,转为由容 ...

  5. main函数argc,argv操作

    使用main(int argc, char *argv[])==main(int argc, char **argv)的基本操作是linux编程的最基本的一步,在windows下也是exe脱离IDE运 ...

  6. ivms4200 远程桌面访问测试过程及问题汇总

    17.11.4 测试存储服务器配置后能否自动录像确认 10:34   4200客户端关闭 10:40  打开4200客户端软件 10:51   关机 10:56  开机,有提示出现,“防火墙阻止... ...

  7. dedecms关键词维护里面字数多的词优先字数少的词的解决办法

    织梦后台的关键词维护默认的情况是字数少的词优先于字数多的词,比如我们有两个这样的词:创业.创业方向,第二个词包含了第一个词,在文章中如果出现“创业方向”这个词,默认情况下只会给创业两个字添加关键词超链 ...

  8. java实现折半查找

    package althorgrim;/** * 1.必须采用顺序存储结果 * 2.关键字必须有序 * @author hanrk-2734 * */public class TestBinarySe ...

  9. 数据持久化-存取方式总结&应用沙盒&文件管理NSFileManager

    iOS应用数据存储的常用方式:  1.XML属性列表   (plist归档)  2.NSUserDefaults (偏好设置)  3.NSKeyedArchiver  归档(加密形式)  4.SQLi ...

  10. 【Henu ACM Round#16 A】 Bear and Game

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 看看什么时候t[i]-t[i-1]>15. 输出t[i-1]+15就好. 不存在这样的i就输出min(t[n]+15,90) ...