在写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++里的指针不同的是他类型化更明显了。什么类型的委托可以初始化什么类型的方法委托变量。这样就可以把函数指针到处传递了。在子弹窗触发父窗体刷新等也基于委托调用也是一个很好的方式。千万别到父页面搞个静态方法这种方式给子页面调额。这种太死了,借助委托可以把方法层层传递给任何要调用的地方。文章来源:https://www.toymoban.com/news/detail-537040.html
iMedicalLIS监听程序的基础就基于线程和委托来实现异步,防止卡UI。文章来源地址https://www.toymoban.com/news/detail-537040.html
到了这里,关于C#线程操作UI控件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!