Winform实现多线程异步更新UI(进度及状体信息)

引言



在进行Winform程序开发需要进行大量的数据的读写操作的时候,往往会需要一定的时间,然在这个时间段里面,界面ui得不到更新,导致在用户看来界面处于假死的状态,造成了不好的用户体验。所以在大量数据操作的应用上,需要使用多线程来处理这种情况。在c#中使用多线程很方便只需要使用System.Threading.Thread的一个实例的Start方法就行了,但是如何实现多线程之间的交互就不是那么简单。本文实现了用子线程去处理数据,并实时更新主线程的ui状态了。下面就开始一步步的去实现异步线程更新ui的demo程序吧。

应用背景 



写入一定量的数据到文本文件中,同时需要在主界面中反应出写入数据的实时进度情况。要求:需要将写入数据封装成一个类。

实现过程



1、首先建立一个winform项目,在主窗体上拖入一个button,一个progressbar,一个lable。如下图所示。

2、编写一个处理数据的类(WriteDate),源代码如下。

  public class DataWrite
    {
        public delegate void UpdateUI(int step);//声明一个更新主线程的委托
        public UpdateUI UpdateUIDelegate;

        public delegate void AccomplishTask();//声明一个在完成任务时通知主线程的委托
        public AccomplishTask TaskCallBack;

        public void Write(object lineCount)
        {
            StreamWriter writeIO = new StreamWriter("text.txt", false, Encoding.GetEncoding("gb2312"));
            string head = "编号,省,市";
            writeIO.Write(head);
            for (int i = 0; i < (int)lineCount; i++)
            {
                writeIO.WriteLine(i.ToString() + ",湖南,衡阳");
                //写入一条数据,调用更新主线程ui状态的委托
                UpdateUIDelegate(1);
            }
            //任务完成时通知主线程作出相应的处理
            TaskCallBack();
            writeIO.Close();
        }
    }

3、主界面中的代码如下:

首先要建立一个委托来实现非创建控件的线程更新控件。

 delegate void AsynUpdateUI(int step);

 

然后编写多线程去启动写入数据的方法以及回调的函数。

     private void btnWrite_Click(object sender, EventArgs e)
        {
            int taskCount = 10000; //任务量为10000
            this.pgbWrite.Maximum = taskCount;
            this.pgbWrite.Value = 0;

            DataWrite dataWrite = new DataWrite();//实例化一个写入数据的类
            dataWrite.UpdateUIDelegate += UpdataUIStatus;//绑定更新任务状态的委托
            dataWrite.TaskCallBack += Accomplish;//绑定完成任务要调用的委托

            Thread thread = new Thread(new ParameterizedThreadStart(dataWrite.Write));
            thread.IsBackground = true;
            thread.Start(taskCount);
        }

        //更新UI
        private void UpdataUIStatus(int step)
        {
            if (InvokeRequired)
            {
                this.Invoke(new AsynUpdateUI(delegate(int s)
                {
                    this.pgbWrite.Value += s;
                    this.lblWriteStatus.Text = this.pgbWrite.Value.ToString() + "/" + this.pgbWrite.Maximum.ToString();
                }), step);
            }
            else
            {
                this.pgbWrite.Value += step;
                this.lblWriteStatus.Text = this.pgbWrite.Value.ToString() + "/" + this.pgbWrite.Maximum.ToString();
            }
        }

        //完成任务时需要调用
        private void Accomplish()
        {
            //还可以进行其他的一些完任务完成之后的逻辑处理
            MessageBox.Show("任务完成");
        }

效果如下:

总结


实现异步更新ui有很多种方法,但是我认为这种方式是比较灵活,能实时的获取到任务进行的状态,并且对之进行相应的处理。这种模式还适用于使用多个线程同时写入不同的数据到不同的文件中去。

源代码下载地址:http://download.csdn.net/detail/mingge38/9378852

时间: 2024-10-21 19:39:23

Winform实现多线程异步更新UI(进度及状体信息)的相关文章

Winform实现多线程异步更新UI(进度及状态信息)

引言 在进行Winform程序开发需要进行大量的数据的读写操作的时候,往往会需要一定的时间,然在这个时间段里面,界面ui得不到更新,导致在用户看来界面处于假死的状态,造成了不好的用户体验.所以在大量数据操作的应用上,需要使用多线程来处理这种情况.在c#中使用多线程很方便只需要使用System.Threading.Thread的一个实例的Start方法就行了,但是如何实现多线程之间的交互就不是那么简单.本文实现了用子线程去处理数据,并实时更新主线程的ui状态了.下面就开始一步步的去实现异步线程更新

android异步更新UI界面的方法

在android平台下,进行多线程编程时,经常需要在主线程之外的一个单独的线程中进行某些处理,然后更新用户界面显示.但是,在主线线程之外的线程中直接更新页面显示的问题是:系统会报这个异常,android.view.viewroot$calledfromwrongthreadexception: only the original thread that created a view hierarchy can touch its views. (只有原始创建这个视图层次(view hierach

Android异步处理二:AsynTask介绍和使用AsyncTask异步更新UI界面

在上一篇(http://blog.csdn.net/xlgen157387/article/details/45269389)中介绍了使用Thread+Handler实现非UI线程更新UI界面的方法步骤,下边做一下如何同构AsyncTask异步任务来更新UI界面. (1)AsyncTask的介绍 通过上图中的AsyncTask的源码结构图可以看到,主要用于重载的方法是doInBackground(),onPreExecute().onPostExecute().onProgressUpdate(

Android异步处理二:使用AsyncTask异步更新UI界面

Android异步处理二:使用AsyncTask异步更新UI界面 - lzc的专栏 - 博客频道 - CSDN.NET 在<Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面>中,我们使用Thread+Handler的方式实现了异步更新UI界面,这一篇中,我们介绍一种更为简洁的实现方式:使用AsyncTask异步更新UI界面. 概述: AsyncTask是在Android SDK 1.5之后推出的一个方便编写后台线程与UI线程交互的辅助类.AsyncTask的

Android异步处理系列文章四篇之二 使用AsyncTask异步更新UI界面

Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面Android异步处理二:使用AsyncTask异步更新UI界面Android异步处理三:Handler+Looper+MessageQueue深入详解Android异步处理四:AsyncTask的实现原理 Android异步处理二:使用AsyncTask异步更新UI界面 概述: AsyncTask是在Android SDK 1.5之后推出的一个方便编写后台线程与UI线程交互的辅助类.AsyncTask的内部实现

WPF中异步更新UI元素

XAML 界面很简单,只有一个按钮和一个lable元素,要实现点击button时,lable的内容从0开始自动递增. <Grid> <Label Name="lable_plus" Content="0"/> <Button Content="Button" Click="button_Click" Height="23" Name="button" Wid

Android 通过广播来异步更新UI

之前的项目里要做一个异步更新UI的功能,但是结果出现了ANR,所以想写个demo来测试到底是哪个地方出现了问题,结果发现原来的思路是没有问题,郁闷~~ 现在这个demo 就是模拟项目里面 的步骤 1.接收到系统的广播(现在模拟为人工发送) 2.广播接收到后,handler通知异步线程从网上下载数据,是异步(模拟为sleep) 3.数据下载完后handler再通知UI更新 下面是主要的两个代码,能够正确运行 package com.example.testanr; import android.s

android异步更新UI的几种方法

前言 ?我们知道在android开发中不能在非ui线程中更新ui,但是,有的时候我们需要在代码中执行一些诸如访问网络.查询数据库等耗时操作,为了不阻塞ui线程,我们时常会开启一个新的线程(工作线程)来执行这些耗时操作,然后我们可能需要将查询到的数据渲染到ui组件上,那么这个时候我们就需要考虑异步更新ui的问题了. android中有下列几种异步更新ui的解决办法: Activity.runOnUiThread(Runnable) View.post(Runnable) long) View.po

winform中如何在多线程中更新UI控件--ListView实时显示执行信息

1.在winform中,所有对UI的操作,都得回到UI线程(主线程)上来,才不会报错 线程间操作无效: 从不是创建控件的线程访问它. 2.在winform中,允许通过Control.invoke对控件进行操作.如下代码: private void btnTest_Click(object sender, EventArgs e) { CheckA(); } private void CheckA() { System.Threading.ThreadPool.QueueUserWorkItem(