zoukankan      html  css  js  c++  java
  • 【转】Windows Mobile 进阶系列——多窗体应用的性能与编程调试1

    【转】Windows Mobile 进阶系列——多窗体应用的性能与编程调试1

    阅读(13评论(0)发表时间:2009年02月14日 14:22

    本文地址:http://qzone.qq.com/blog/84143222-1234592534

    本文标签: 窗体 线程 性能 调试 int
    摘要:在资源有限的Windows Mobile移动设备上面,具有多窗体的应用程序的性能问题是值得我们去关注的。本文阐述了如何优化多窗体应用程序的性能,提高加载速度的方案以及在性能调试过程中常用的编程调试的技巧
    Keywords
    Windows Mobile,多窗体,性能,调试,C# 
    有朋友说这个系列的前面几篇文章太理论了,不好懂。我很理解,不过我的确得把一些理论性的文章安排在前面,也请筒子们耐心,从现在开始后面的文章会比较轻松一点 J
    1.      窗体加载性能
    窗体的加载主要是在Form的load事件处理函数里面完成的。所以,我们首先需要尽量使Form_Load里面的代码最小化。把那些负荷比较重的任务放到后台线程上完成,尽量不去阻塞和“耽误”加载窗体的线程。
    熟悉.Net Framework的朋友应该知道,.NET Framework2.0以上的版本中引入了一个叫做BackgroundWorker的组件用来实现上述功能。把一些高负荷的工作放到BackgroundWorker组件中去执行,不对主线程造成阻塞。遗憾的是目前在.NET CF中并不支持这个组件,不过你仍然可以使用线程池(Threadpool)来实现类似的功能。
    下面的示例,对使用和不使用线程池做同样的任务所用的时间做了比较。
    我们先把一个比较重的任务放到主线程上去做:
            private void Form2_Load(object sender, EventArgs e)
           {
    //计时起点
                int start = Environment.TickCount;
                int end = 0;
                for (int num = 0; num < 1000; num++)
                {
                    this.Text = num.ToString();
                }
    //计时终点
                end = Environment.TickCount;
                Debug.WriteLine("Single thread list-populating time (ms) " + (end - start));
            }

    所做的工作就是更新form的标题1000次。结果我们可以在output栏看到如下的输出:

    可以看到,在Form2的加载过程中,在这样一个任务上(我们仅仅用来模拟某些必不可少的工作)花费了接近1秒钟(916ms)时间。而在这一秒钟时间内,用户是处于等待的状态。显然,这并不是一个好的方案,毕竟在加载Form的时间就让用户等那么久是不厚道的。
    下面是使用Threadpool的一个解决方案:
         private delegate void AddDelegate(int num);

            private void Form2_Load(object sender, EventArgs e)
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(HeavyWork));
            }

            private void HeavyWork (object o)
            {
    //计时起点
                int start = Environment.TickCount;

                int end = 0;

                int count = 1000;

                try
                {
                    for (int i = 0; i < count; i++)
                    {
                        if (this.InvokeRequired)
                        {
                            object[] args = new object[1];
                           args[0] = i;
                            this.BeginInvoke(new AddDelegate(n => { this.Text = n.ToString(); }),args);
                        }
                        else
                        {
                            this.Text = i.ToString();
                       }
                    }
                }
                catch(Exception ex)
                {
                    Debug.Write(ex.ToString());
                }
    //计时终点
                end = Environment.TickCount;
                Debug.WriteLine("Work-thread asynchronize list-populating time (ms) "+ (end - start));
            }



    线程池的某一条线程会去执行挂载在WaitCallback 委托上的“等待回调”的HeavyWork方法,并通过Control.BeginInvoke()方法以异步的方式更新Form的标题。我们在output栏中可以看到如下的输出


    我们看到,这种利用多线程的异步方式仅花费了169ms,与前面的结果相比,节约了800ms时间。
    注意:不同的设备,不同的调试环境所用的时间可能略有不同
    当然,并不是非要启用线程的线程池的线程。你完全可以自己创建一条线程做一些额外的工作,或者直接使用AsyncCallBack委托,MSDN上AsyncCallBack的例子很经典,值得大家看一下。不管使用什么方法,我们的目的就在于使用户能最快的看到他想看到的东西,不要让用户对着旋转的光标心叹。
  • 相关阅读:
    E: 无法获得锁 /var/lib/dpkg/lock-frontend
    Ubuntu 18.04 更换apt源
    ubuntu18.04
    小a与“204”------数列、排序
    星际穿越
    合唱团---DP
    分苹果---暴力
    地牢逃脱----DFS搜索最优解
    下厨房---map/字符串查询
    hdu 2654 Be a hero
  • 原文地址:https://www.cnblogs.com/chinatefl/p/1431358.html
Copyright © 2011-2022 走看看