C#线程操作UI控件

在写winform程序时候,如果时间长的操作不用线程操作。那么会卡死UI,点击界面就体现为未响应。为此需要对耗时操作用线程处理,比如检验的监听程序就是一个死循环,不停检查文件夹或数据库又没有数据,然后上传。如果不时有线程,在数据多的情况,程序是基本点不动的,这样体验就很不好。

1.首先拖个文本框准备用线程给里面写文本
C#线程操作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();
        }

        /// 
        /// 加载方法
        /// 
        /// 
        /// 
        private void Form1_Load(object sender, EventArgs e)
        {
            //用线程写文本
            Thread t = new Thread(WriteTxt);
            t.Start();

        }

        /// 
        /// 写文本
        /// 
        public void WriteTxt()
        {
            for(int i=0;i<100;i++)
            {
                richTextBox1.Text += "第" + i + "行\n";
            }

        }

    }
}

3.运行报错,这里报错不能从线程访问UI控件
C#线程操作UI控件_第2张图片

那么对于线程运行长时间操作,想和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
{
    /// 
    /// 写日志委托
    /// 
    /// 
    public delegate void WriteInfoDelegate(string info);

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        /// 
        /// 加载方法
        /// 
        /// 
        /// 
        private void Form1_Load(object sender, EventArgs e)
        {
            //用线程写文本
            Thread t = new Thread(WriteTxt);
            t.Start();

        }

        /// 
        /// 写日志代理方法
        /// 
        /// 
        public void WriteInfoProxy(string info)
        {
            //组装参数
            object[] paras = new object[] { info };
            //在UI线程执行委托
            this.Invoke(new WriteInfoDelegate(SetTxt), paras);
        }

        /// 
        /// 操作控件逻辑
        /// 
        /// 
        public void SetTxt(string info)
        {
            richTextBox1.Text += info;
        }

        /// 
        /// 写文本
        /// 
        public void WriteTxt()
        {
            for(int i=0;i<100;i++)
            {
                WriteInfoProxy("第" + i + "行\n");
            }

        }

    }
}

就不会异常了
C#线程操作UI控件_第3张图片

C#的委托我理解为函数指针,和C及C++里的指针不同的是他类型化更明显了。什么类型的委托可以初始化什么类型的方法委托变量。这样就可以把函数指针到处传递了。在子弹窗触发父窗体刷新等也基于委托调用也是一个很好的方式。千万别到父页面搞个静态方法这种方式给子页面调额。这种太死了,借助委托可以把方法层层传递给任何要调用的地方。

iMedicalLIS监听程序的基础就基于线程和委托来实现异步,防止卡UI。

你可能感兴趣的:(C#,c#,ui,开发语言)