前言

多线程刷新界面主要用到多线程,委托,线程安全、事件等一系列高难度的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控件,解决界面卡顿问题(转)的更多相关文章

  1. C# Winform使用线程,委托定时更新界面UI控件,解决界面卡顿问题(转载)

    一.定时执行主界面控件值 1.利用定时器 Thread t = null; private void InitTSJK() { t = new Thread(new ThreadStart(GetDa ...

  2. 多线程环境的UI控件属性更新

    Winform: public delegate void UpadataTextCallBack(string str,TextBox text); public void UpadtaText(s ...

  3. WPF / Win Form:多线程去修改或访问UI线程数据的方法( winform 跨线程访问UI控件 )

    WPF:谈谈各种多线程去修改或访问UI线程数据的方法http://www.cnblogs.com/mgen/archive/2012/03/10/2389509.html 子线程非法访问UI线程的数据 ...

  4. C# Winform 跨线程更新UI控件常用方法汇总(多线程访问UI控件)

    概述 C#Winform编程中,跨线程直接更新UI控件的做法是不正确的,会时常出现“线程间操作无效: 从不是创建控件的线程访问它”的异常.处理跨线程更新Winform UI控件常用的方法有4种:1. ...

  5. C# Winform 跨线程更新UI控件常用方法总结(转)

    出处:http://www.tuicool.com/articles/FNzURb 概述 C#Winform编程中,跨线程直接更新UI控件的做法是不正确的,会时常出现“线程间操作无效: 从不是创建控件 ...

  6. C#学习之在辅助线程中修改UI控件----invoke方法

    Invoke and BeginInvoke 转载地址:http://www.cnblogs.com/worldreason/archive/2008/06/09/1216127.html 在Invo ...

  7. 富客户端 wpf, Winform 多线程更新UI控件

    前言 在富客户端的app中,如果在主线程中运行一些长时间的任务,那么应用程序的UI就不能正常相应.因为主线程要负责消息循环,相应鼠标等事件还有展现UI. 因此我们可以开启一个线程来格外处理需要长时间的 ...

  8. (转).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 ...

  9. WinForm/Silverlight多线程编程中如何更新UI控件的值

    单线程的winfom程序中,设置一个控件的值是很easy的事情,直接 this.TextBox1.value = "Hello World!";就搞定了,但是如果在一个新线程中这么 ...

  10. 理解SynchronizationContext,如何在Winform里面跨线程访问UI控件

    SynchronizationContext 类是一个基类,可提供不带同步的自由线程上下文. 此类实现的同步模型的目的是使公共语言运行库内部的异步/同步操作能够针对不同的异步模型采取正确的行为.此模型 ...

随机推荐

  1. Cobaltstrike —— shellcode分析(一)

    前言 搞iot搞久了,换个方向看看,改改口味. windows 常见结构体 在分析Cobaltstrike-shellcode之前我们得先了解一下windows下一些常见的结构体. X86 Threa ...

  2. CF846E - Chemistry in Berland

    题意:有一颗树,每个点上有 \(b_i\) 东西,从叶子往上的汇率是 \(1:1\),从父亲往下的汇率是 \(k:1\),求能否使每个点的东西都不少于 \(a_i\). 我们发现,从上往下肯定是不划算 ...

  3. 深度学习框架Pytorch学习笔记

    由于工作原因,需要使用到深度学习pytorch框架,所以,跟随视频学习了深度学习框架的使用方法,视频链接如下: PyTorch深度学习快速入门教程(绝对通俗易懂!)[小土堆]_哔哩哔哩_bilibil ...

  4. 禁用a标签点击事件

    a标签是没有disable属性的 ,如果想用disable 禁用a标签的点击事件,也可以实现: 1.a标签要用disable属性,必须和pointer-events属性一起使用, html代码: &l ...

  5. 华为S6720S-S24S28X-A配置参数

  6. 多个module的verilog文件分割为多个文件

    python 分割含有多个module的verilog文件,按照module名来命名文件 import re # 读取 Verilog 文件 with open('test.v', 'r') as f ...

  7. 524. 通过删除字母匹配到字典里最长单词 (Medium)

    问题描述 524. 通过删除字母匹配到字典里最长单词 (Medium) 给你一个字符串 s 和一个字符串数组 dictionary ,找出并返回 dictionary 中最长的字符串,该字符串可以通过 ...

  8. 0624.python入门

    课堂笔记 一 编程语言 什么是编程语言? 上面提及的能够被计算机所识别的表达方式即编程语言,语言是沟通的介质,而编程语言是程序员与计算机沟通的介质.在编程的世界里,计算机更像是人的奴隶,人类编程的目的 ...

  9. 数值分析之数值积分 4.X

    求积公式 \[\int_{a}^{b} f(x) \mathrm{d} x \approx \sum_{k=0}^{n} A_{k} f\left(x_{k}\right) \] \(A_k\) 为求 ...

  10. SpringBoot中常见问题

    Invalid bound statement(not found): 异常原因:编译之后的mapper文件中的.xml文件未编译, 解决方法:在pom.xml文件中添加如下配置,添加位置为build ...