当前位置:网站首页>C#线程操作UI控件
C#线程操作UI控件
2022-07-29 13:19:00 【Walk in loosing】
在写winform程序时候,如果时间长的操作不用线程操作。那么会卡死UI,点击界面就体现为未响应。为此需要对耗时操作用线程处理,比如检验的监听程序就是一个死循环,不停检查文件夹或数据库又没有数据,然后上传。如果不时有线程,在数据多的情况,程序是基本点不动的,这样体验就很不好。
1.首先拖个文本框准备用线程给里面写文本
2.测试代码,创建一个线程,直接操作UI控件
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace ThreadUI
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
/// <summary>
/// 加载方法
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Form1_Load(object sender, EventArgs e)
{
//用线程写文本
Thread t = new Thread(WriteTxt);
t.Start();
}
/// <summary>
/// 写文本
/// </summary>
public void WriteTxt()
{
for(int i=0;i<100;i++)
{
richTextBox1.Text += "第" + i + "行\n";
}
}
}
}
3.运行报错,这里报错不能从线程访问UI控件
那么对于线程运行长时间操作,想和UI交互怎么办呢?
这里需要用委托解决线程和UI交互:
1.先定义一个委托
2.把操作UI的方法再用委托包一层
3.线程调用包装的方法
调整代码如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace ThreadUI
{
/// <summary>
/// 写日志委托
/// </summary>
/// <param name="info"></param>
public delegate void WriteInfoDelegate(string info);
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
/// <summary>
/// 加载方法
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Form1_Load(object sender, EventArgs e)
{
//用线程写文本
Thread t = new Thread(WriteTxt);
t.Start();
}
/// <summary>
/// 写日志代理方法
/// </summary>
/// <param name="info"></param>
public void WriteInfoProxy(string info)
{
//组装参数
object[] paras = new object[] {
info };
//在UI线程执行委托
this.Invoke(new WriteInfoDelegate(SetTxt), paras);
}
/// <summary>
/// 操作控件逻辑
/// </summary>
/// <param name="info"></param>
public void SetTxt(string info)
{
richTextBox1.Text += info;
}
/// <summary>
/// 写文本
/// </summary>
public void WriteTxt()
{
for(int i=0;i<100;i++)
{
WriteInfoProxy("第" + i + "行\n");
}
}
}
}
就不会异常了
C#的委托我理解为函数指针,和C及C++里的指针不同的是他类型化更明显了。什么类型的委托可以初始化什么类型的方法委托变量。这样就可以把函数指针到处传递了。在子弹窗触发父窗体刷新等也基于委托调用也是一个很好的方式。千万别到父页面搞个静态方法这种方式给子页面调额。这种太死了,借助委托可以把方法层层传递给任何要调用的地方。
iMedicalLIS监听程序的基础就基于线程和委托来实现异步,防止卡UI。
边栏推荐
猜你喜欢
随机推荐
全开放式耳机怎么样?不塞耳朵的蓝牙耳机推荐
【个人收藏】一些比较有用的链接
你真的会用Console.log吗?
简单了解单例模式
Sentinel 2A data preprocessing and calculation of six common vegetation indices in snap software
[Numpy] np.select
浅谈防勒索病毒方案之主机加固
trivy如何从非关系型数据库查询数据
grid的使用
AI全流程开发难题破解之钥
万字长文,揭秘华为数据治理体系!
【LeetCode】Day105-递增的三元子序列
Go - reading (7), CopySheet Excelize API source code (the from and to the int)
gdb调试常用概念整理
程序员是职业病高发群体,别天真的以为只有秃头那么简单,才不是呢。
JS_ deleting the invalid data in the array undefined '0' null false NaN
即时通讯移动端开发之网络连接优化
十种实现延迟任务的方案
[10:00 Open Class]: Application Exploration of Kuaishou GPU/FPGA/ASIC Heterogeneous Platform
JUC阻塞队列-ArrayBlockingQueue









