当前位置: 程晨旭的博客 > 学习笔记>正文

Winform异步更新UI界面的方法三:真正线程安全的this.Invoke 匿名委托

this.Invoke可以方便的在子线程中对UI界面进行访问,并且是真正的线程安全的.

单纯这一个委托无法实现回调,也就是绑定完成之后无法提供一个后续的操作

使用场景为需要远程读取或处理数据(耗费时间),然后直接绑定到控件显示,无其他后续操作要求.

本方法使用的时候要注意:

                this.Invoke((Action)delegate
                {
                    //这里只应该放置UI控件访问的代码,其他的数据读取和处理要放到外面,因为实际上这个代码块是在主线程中执行的.                    
                    this.label2.Text = i.ToString();
                });
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace chengchenxu.ActionEMO
{
    public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //启动累加线程 不停改变Label2内容
            Thread thread2 = new Thread(Add);
            thread2.IsBackground = true;
            thread2.Start();
        }
        private void Add()
        {
            for (int i = 0; i < 50; i++)
            {
                Thread.Sleep(1000);

                //采用匿名委托方式进行访问UI线程
                this.Invoke((Action)delegate
                {
                    //这里的语句实际上是在主线程执行的
                    //子线程委托主线程进行更新
                    //如果下面这样把for语句挪到this.Invoke内 主界面会卡死
                    //this.Invoke((Action)delegate
                    //{
                    //    for (int i = 0; i < 50; i++)
                    //    {
                    //        Thread.Sleep(1000);
                    //        this.label2.Text = i.ToString();
                    //    }

                    //});
                    this.label2.Text = i.ToString();
                });
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //另起线程3
            Thread thread3 = new Thread(Get);
            thread3.Start();
        }

        private void Get()
        {
            
            try
            {
                //尝试从线程3访问主界面 拒绝访问
                this.label2.Text = "efsadddddddddddddddd";



                //如果这里用上this.Invoke委托,则可以访问.
                //this.Invoke((Action)delegate
                //{
                //    this.label2.Text = "efsadddddddddddddddd";
                //});
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //从主线程中访问label2是可以访问的,因为他本来就在主线程内
            this.label2.Text = "efsadddddddddddddddd";
            this.label2.ForeColor = Color.Red;
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            
        }
    }
}


DEMO下载:chengchenxu.ActionEMO - 副本.rar


本文为博主原创,转载请保留出处:
http://www.chengchenxu.com/Article/31/thisInvoke

‹‹ 上一篇 下一篇 ››

评论列表:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。