C# Winform 多线程更新界面UI控件,解决界面卡顿问题(转)
前言
多线程刷新界面主要用到多线程,委托,线程安全、事件等一系列高难度的C#操作。
1、使用timer控件对要刷新的控件进行定时刷新
对刷新频率要求不高的时候,可以使用该方法。
2、刷新UI控件
在开发软件时经常会需要更新界面上的某个控件来显示相关的信息,为了让程序执行中不出现界面卡死的现像,最好的方法就是“多线程+委托”来解决。
控件:pictureBox1
public delegate void DeleMyDelegate();//定义委托
DeleMyDelegate deleMyDelegate;//声明委托
public void DeleMy()//定义信息函数
{
pictureBox1.Refresh();
}
public void Pic_Show()
{
deleMyDelegate = new DeleMyDelegate(DeleMy);//绑定委托
this.pictureBox1.Invoke(deleMyDelegate);
}
private void button1_Click(object sender, EventArgs e)
{
Thread myThread = new Thread(Pic_Show);
myThread.Start();
}
控件:richTextBox1
Thread myThread;
public delegate void MyDelegateUI(); //定义委托类型
MyDelegateUI myDelegateUI; //声明委托对象
public Form1()
{
InitializeComponent();
myThread = new Thread(doWork);
myDelegateUI = new MyDelegateUI(initAll);//绑定委托
}
private void initAll() //信息处理函数定义
{
richTextBox1.AppendText("TEST line \r");
}
private void doWork()
{
for (int i = 0; i < 10; i++)
{
Thread.Sleep(100);
this.Invoke(myDelegateUI); //richTextBox1.AppendText("TEST line \r");
Application.DoEvents();
}
}
private void button1_Click(object sender, EventArgs e)
{
myThread.Start();
}
3、工作线程中刷新主界面控件状态
(1)工作线程类
public class Work
{
private volatile static Work instanceWork; // 单例
public delegate void InvokeListBox(int i);
public InvokeListBox invokeOthers;
/// <summary>
/// 构造函数
/// </summary>
public Work()
{
}
/// <summary>
/// 对外接口,获取单例
/// </summary>
/// <returns></returns>
public static Work GetInstance()
{
if (null == instanceWork)
{
instanceWork = new Work();
}
return instanceWork;
}
/// <summary>
/// 业务函数,在工作过程中将状态传给主界面
/// </summary>
public void DoSomething()
{
for (int i = 0; i < 20; i++)
{
Thread.Sleep(1000);
invokeOthers(i);
}
}
}
(2)主界面布局及代码

private delegate void InvokeListBox(string strCon); // 刷新ListBox的委托。
private InvokeListBox invokeListBox;
private Work wk; //工作线程对象
public Form1()
{
InitializeComponent();
wk = Work.GetInstance(); //单例模式初始化工作线程对象
wk.invokeOthers = new Work.InvokeListBox(ReciveData); // 绑定,接收工作线程过来的数据
invokeListBox = new InvokeListBox(RefrushListBox); // 绑定,刷新界面ListBox控件
}
private void button1_Click(object sender, EventArgs e)
{
Thread th = new Thread(new ThreadStart(wk.DoSomething));
th.Start();
}
/// <summary>
/// 接收工作线程过来的数据,更新界面
/// </summary>
/// <param name="i"></param>
public void ReciveData(int i)
{
string strConten = i.ToString() + " 更新";
if (this.listBox1.InvokeRequired)
{
this.listBox1.Invoke(invokeListBox, new object[] { strConten });
}
}
/// <summary>
/// 具体刷新界面函数
/// </summary>
/// <param name="_str"></param>
public void RefrushListBox(string _str)
{
this.listBox1.Items.Add(_str);
}
(3)说明
本例子中有两个委托:1、Work.cs中的委托变量 ivokeOthers,作用是将信息传递给给主界面对应的函数:ReceiveData()。2、Form_MainUI.cs中的委托变量 invokeListBox,作用是刷新界面控件ListBox_state的内容。点击“开始工作”按钮后,工作线程启动,调用Work.cs中DoSomeThing()函数。由于Form_MainUI.cs中的函数ReceiveData()函数绑定了Work.cs中的委托ivokeOthers,所以当Work.cs中DoSomeThing被调用时ivokeOthers会把变量i传递给ReceiveData()。ReceiveData()接收到数据后,通过Invoke调用刷函数RefrushListBox()修改主界面ListBox_State的内容。
(4)总结
1)不要惧怕委托、事件的复杂的概念,动手操作练习一下,就简单的把它们当做传递消息的载体。
2)在工作线程中修改主界面其它控件的内容、状态、图片等操作类似,可以自己动手试试。
3)本小结在实现刷新主界面控件的时候使用了单例模式,不使用单例模式也完全可以实现,加上单例是为了让调用更加方便,在大项目开发中就会体现其优势。
https://blog.csdn.net/kingshown_WZ/article/details/89322499?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param
C# Winform 多线程更新界面UI控件,解决界面卡顿问题(转)的更多相关文章
- C# Winform使用线程,委托定时更新界面UI控件,解决界面卡顿问题(转载)
一.定时执行主界面控件值 1.利用定时器 Thread t = null; private void InitTSJK() { t = new Thread(new ThreadStart(GetDa ...
- 多线程环境的UI控件属性更新
Winform: public delegate void UpadataTextCallBack(string str,TextBox text); public void UpadtaText(s ...
- WPF / Win Form:多线程去修改或访问UI线程数据的方法( winform 跨线程访问UI控件 )
WPF:谈谈各种多线程去修改或访问UI线程数据的方法http://www.cnblogs.com/mgen/archive/2012/03/10/2389509.html 子线程非法访问UI线程的数据 ...
- C# Winform 跨线程更新UI控件常用方法汇总(多线程访问UI控件)
概述 C#Winform编程中,跨线程直接更新UI控件的做法是不正确的,会时常出现“线程间操作无效: 从不是创建控件的线程访问它”的异常.处理跨线程更新Winform UI控件常用的方法有4种:1. ...
- C# Winform 跨线程更新UI控件常用方法总结(转)
出处:http://www.tuicool.com/articles/FNzURb 概述 C#Winform编程中,跨线程直接更新UI控件的做法是不正确的,会时常出现“线程间操作无效: 从不是创建控件 ...
- C#学习之在辅助线程中修改UI控件----invoke方法
Invoke and BeginInvoke 转载地址:http://www.cnblogs.com/worldreason/archive/2008/06/09/1216127.html 在Invo ...
- 富客户端 wpf, Winform 多线程更新UI控件
前言 在富客户端的app中,如果在主线程中运行一些长时间的任务,那么应用程序的UI就不能正常相应.因为主线程要负责消息循环,相应鼠标等事件还有展现UI. 因此我们可以开启一个线程来格外处理需要长时间的 ...
- (转).NET 4.5中使用Task.Run和Parallel.For()实现的C# Winform多线程任务及跨线程更新UI控件综合实例
http://2sharings.com/2014/net-4-5-task-run-parallel-for-winform-cross-multiple-threads-update-ui-dem ...
- WinForm/Silverlight多线程编程中如何更新UI控件的值
单线程的winfom程序中,设置一个控件的值是很easy的事情,直接 this.TextBox1.value = "Hello World!";就搞定了,但是如果在一个新线程中这么 ...
- 理解SynchronizationContext,如何在Winform里面跨线程访问UI控件
SynchronizationContext 类是一个基类,可提供不带同步的自由线程上下文. 此类实现的同步模型的目的是使公共语言运行库内部的异步/同步操作能够针对不同的异步模型采取正确的行为.此模型 ...
随机推荐
- Hexo系列(三):Hexo主题
作者:独笔孤行 官网: http://anyamaze.com 公众号:云实战 Hexo支持更换主题,支持多种主题模式,也支持自定义主题. Hexo主题地址1:https://hexo.io ...
- 找素数(java)
什么是素数? 质数又称素数.一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数:否则称为合数(规定1既不是质数也不是合数). 实际案例 比如我们想找出1-1000的所有素数 思路1 ...
- Cobalt Strike 之: Aggressor Script
郑重声明: 本笔记编写目的只用于安全知识提升,并与更多人共享安全知识,切勿使用笔记中的技术进行违法活动,利用笔记中的技术造成的后果与作者本人无关.倡导维护网络安全人人有责,共同维护网络文明和谐. Co ...
- yarn的基础语法:yarn安装完vue cli3后提示不是内部命令
: 第一步:安装nodejs: 第二步:全局安装vue-cli 解决方案: 全局搜索vue.cmd 将vue.cmd所在的路径添加到环境变量Path后面.再执行vue -V即可.
- 让CSS flex布局最后一行列表左对齐的N种方法
原文链接https://mp.weixin.qq.com/s?__biz=MjM5MDA2MTI1MA==&mid=2649091838&idx=1&sn=fa4e1ed1e0 ...
- 【C学习笔记】day5-2 写代码可以在整型有序数组中查找想要的数字, 找到了返回下标,找不到返回-1.(折半查找)
#include <stdio.h> #include <stdlib.h> int find(int s) { int n = 0; scanf_s("%d&quo ...
- java读取虚拟串口数据
语言:java 虚拟串口工具:Virtual Serial Port Driver Pro 9.0,选择pairing模块下,点击add virtual paring按钮即可创建串口对,还无法自定义o ...
- pgsql计算占比
SELECT len/sum(len)over(partition by road_id) param from road_jcpd_section
- Qt构造函数和析构函数报错undefinedreferenceto`vtable for 。。。。'
百度了一堆,说各种的都有,无非就是说什么构造函数没有实现父类的纯虚函数,但是我明明继承并实现了,,,最后发现可能就是单纯的Qtcreater抽风了,一开始在构造里面清理了项目,发现不行. 于是一不做二 ...
- GPT和MBR分区格式
目前市面上磁盘有两个格式,一种是GPT(Master Boot Record)分区一种是MBR(Master Boot Record)分区. 像UEFI用于取代老旧的BIOS,而GPT则为的是取代老旧 ...