前言
多线程刷新界面主要用到多线程,委托,线程安全、事件等一系列高难度的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;
/// /// 构造函数
///
public Work()
{
}
/// /// 对外接口,获取单例
///
///
public static Work GetInstance()
{
if (null == instanceWork)
{
instanceWork = new Work();
}
return instanceWork;
}
/// /// 业务函数,在工作过程中将状态传给主界面
///
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();
}
【c#|c# 多线程界面卡顿_C# Winform 多线程更新界面UI控件,解决界面卡顿问题】/// /// 接收工作线程过来的数据,更新界面
///
///
public void ReciveData(int i)
{
string strConten = i.ToString() + " 更新";
if (this.listBox1.InvokeRequired)
{
this.listBox1.Invoke(invokeListBox, new object[] { strConten });
}
}
/// /// 具体刷新界面函数
///
///
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)本小结在实现刷新主界面控件的时候使用了单例模式,不使用单例模式也完全可以实现,加上单例是为了让调用更加方便,在大项目开发中就会体现其优势。
推荐阅读
- c#|c# 多线程界面卡顿_C# Winform 多线程更新界面UI控件,解决界面卡顿问题(转)
- c#|c# 多线程界面卡顿_C# Winform使用线程,委托定时更新界面UI控件,解决界面卡顿问题...
- WPF|图片等可视化元素缩放变换及中心点设置
- C#|c#子线程与主线程之间的通信
- WPF|c# Bartender打印开发详解
- 精选毕业设计完整源码+论文|asp毕业设计——基于C#+asp.net+cs的CS应用程序平台多语种技术设计与实现(毕业论文+程序源码)——平台多语种技术
- 精选毕业设计完整源码+论文|asp毕业设计——基于C#+asp.net+cs的即时通信系统设计与实现(毕业论文+程序源码)——即时通信系统
- 精选毕业设计完整源码+论文|asp毕业设计——基于C#+asp.net+ACCESS的电子商务网站设计与实现(毕业论文+程序源码)——电子商务网站
- C#|c# 字符串与16进制ASCII码相到转换