zoukankan      html  css  js  c++  java
  • (转)【C#利用后台动态加载数据】Winform“防界面卡死”

    原文地址:

    http://www.cnblogs.com/Zeech-Lee/archive/2011/10/14/2212376.html

    废话:最近遇到的项目发现,对于Winform获取大数据量时,界面假死,体验效果非常差。身为测试员,有义务也有责任提出BUG。每次测试都面对卡了超过5秒的界面,实在是一种折磨,更是一种自杀行为。与是自己便研究了下,可以通过多线程来处理,当然也可以通过后台来获取数据。如果用多线程的话可以解决界面卡死的情况,但是对于动态加载数据的话可能复杂些。因为多线程的话,需要执行完一个线程再把数据更新出来,智能化不够高。使用后台的话,可以随时报告获取的数据,能够精确到某一条,而且使用起来很方便,因为是已经封装好了的。


    所使用的类:using System.ComponentModel下的BackgroundWorker ;


    该类下有四个重要的方法:DoWork、ProgressChanged、RunWorkerCompleted、RunWorkerAsync,两个重要的属性WorkerSupportsCancellation、WorkerReportsProgress


    方法:


    1.DoWork:意思就是利用后台具体做什么,绑定时间时传入的参数是方法名


    2.ProgressChanged:进度发生变化时后台该做什么,绑定时间时传入的参数是方法名


    3.RunWorkerCompleted:后台工作完后该做什么,绑定时间时传入的参数是方法名


    4.RunWorkerAsync:启用后台,后台开始运行


    属性:


    1.WorkerSupportsCancellation:是否支持异步取消


    2.WorkerReportsProgress:是否报告进度更新,这个属性很重要,必须启用才能对进度进行报告


    下面进入后台动态加载数据的例子:


    我们先做一个简单的界面如图:



    需要的功能是:点击开始,开始一个一个列出C盘下的文件名,同时进度条显示进度。

    第一个方法,把文件名添加到listview里面的添加方法,在此为了模拟取数据时网络,速度慢的情况Thread.Sleep(500),休眠了0.5秒:


    View Code
     1  public void Add(object sender, DoWorkEventArgs e)
    2 {
    3 DirectoryInfo di = new DirectoryInfo(@"C:/");
    4 foreach (FileInfo item in di.GetFiles())
    5 {
    6 ListViewItem lvt = new ListViewItem();//用listviewItem来存储获取到文件的信息
    7 lvt.Text = item.FullName;
    8 lvt.SubItems.Add(DateTime.Now.ToLongTimeString());
    9 Thread.Sleep(500);
    10 Bw.ReportProgress(listView1.Items.Count,lvt);//把当前的进度报告出去,获取到第几个文件和该文件的信息
    11 }
    12
    13 }

    第二个方法,获取到进度后,对进度进行报告:


    View Code
    1  public void Progress(object sender, ProgressChangedEventArgs e)
    2 {
    3 progressBar1.Value = e.ProgressPercentage;//获取第几个文件,用来改变进度条的进度
    4 ListViewItem lv = e.UserState as ListViewItem;
    5 listView1.Items.Add(lv);//把最新获取到的文件信息添加到listview
    6 }

    第三个方法在本例子就显得像鸡肋了,当后台运行完毕后进行的事件:


    1   public void End(object sender, AsyncCompletedEventArgs e)
    2 {
    3 progressBar1.Value = 0;//进度条清0
    4 }

    最后在按钮双击事件中写入如下方法:


    View Code
     1   private void button1_Click(object sender, EventArgs e)
    2 {
    3 DirectoryInfo di = new DirectoryInfo(@"C:/");
    4 FileInfo[] fi = di.GetFiles();
    5 progressBar1.Maximum = fi.Length - 1;//设置进度条的最大值
    6 Bw.WorkerSupportsCancellation = true;
    7 Bw.WorkerReportsProgress = true;
    8 Bw.DoWork += new DoWorkEventHandler(Add);//绑定事件
    9 Bw.ProgressChanged += new ProgressChangedEventHandler(Progress);
    10 Bw.RunWorkerCompleted+=new RunWorkerCompletedEventHandler(End);
    11 Bw.RunWorkerAsync();
    12 }

    注意:在后台中定义三个方法的时候,格式必须是套用模版。

    大家可以运行下效果,显然这样才是用户所需要的,大数据量若要一次性取出或者是单线程来操作的话,体验效果极差。

    软件若要想得到认可,功能算是一方面,用户体验也发挥着举足重轻的作用。虽然某软件使用了什么很先进的技术,但是用户体验效果极差,用户往往会权衡下选择


    喜欢我的话,就关注我吧!
  • 相关阅读:
    tyvj 1031 热浪 最短路
    【bzoj2005】 [Noi2010]能量采集 数学结论(gcd)
    hdu 1394 Minimum Inversion Number 逆序数/树状数组
    HDU 1698 just a hook 线段树,区间定值,求和
    ZeptoLab Code Rush 2015 C. Om Nom and Candies 暴力
    ZeptoLab Code Rush 2015 B. Om Nom and Dark Park DFS
    ZeptoLab Code Rush 2015 A. King of Thieves 暴力
    hdoj 5199 Gunner map
    hdoj 5198 Strange Class 水题
    vijos 1659 河蟹王国 线段树区间加、区间查询最大值
  • 原文地址:https://www.cnblogs.com/fcsh820/p/2224080.html
Copyright © 2011-2022 走看看