zoukankan      html  css  js  c++  java
  • 从获取QQ验证码谈如何改进用户体验,提高程序的响应效果

    很久没写博客了,最近没有什么惊天地、泣鬼神的大作,就从小处着眼,总结一些开发过程中的一些心得和见解吧。

    众所周知,互联网改变生活,现在是验证码大行其道的年代,基本上主要涉及用户信息注册、登录、提交数据等,都来一个验证码来限制下,QQ在这方面可真是运用到了极致,因此做QQ的开发,必须了解如何处理验证码的问题。一般验证码是通过一个带参数的URL获取到一个数字字符图片,由于网络原因,一般返回比较缓慢,所以如果要提高用户体验和程序的响应速度,就必须采用改良一点的方法来进行处理。

    我们先从一个正常的操作讲起,逐步改进,看看效果及使用情况,如一般的处理就是把它封装在一个独立的函数中,在触发事件的地方调用该函数,如下所示。

            public void GetNewImage()
            {
                HttpHelper httpHelper 
    = new HttpHelper();
                
    using (Stream s = httpHelper.GetStream("http://ptlogin2.qq.com/getimage?aid=3000801&0.43878429697395826", Portal.gc.cookieQun))
                {
                    
    if (s == null)
                    {
                        MessageUtil.ShowWarning(
    "获取登陆码错误,请检查您的网络!");
                        
    return;
                    }
                    pictureBox1.Image 
    = Image.FromStream(s);
                }
            }

    这种方式方式是一般的处理方式,有时候界面会因为获取网络数据而有停顿,除非你的网络非常好,所以可以把它放到一个独立的线程中进行处理,通过hreadPool.QueueUserWorkItem来进行线程处理,如下代码所示:

            public void GetNewImage()
            {
                ThreadPool.QueueUserWorkItem(GetNewImageThread, 
    null);
            }

            
    private void GetNewImageThread(object obj)
            {
                
    using (Stream s = httpHelper.GetStream("https://mail.qq.com/cgi-bin/getverifyimage?aid=23000101&f=html&ck=1&31997", EmailCookie))
                {
                    
    if (s == null)
                    {
                        SetTips(
    "获取登陆码错误,请检查您的网络!");
                        
    return;
                    }

                    
    this.pictureBox1.Invoke(new MethodInvoker(delegate()
                    {
                        
    this.pictureBox1.Image = Image.FromStream(s);
                    }));
                }
            }

     这样已经比较好的处理界面停顿等不友好的问题了,不过有时候,因为使用了Invoke函数,可能会出现一些线程间的异常,如你关闭了窗口,而进行还在运行,就会出现一些问题,但是还是相对比较好的解决途径。

     偶尔一天,看到一个比较好的后台线程封装类QueuedBackgroundWorker,使用效果还比较不错,虽然代码多了一些,不过处理起来效果还真的不错,还支持取消线程操作等功能,整个后台线程以及获取验证码的操作代码如下所示,整个代码运行效果不错,而且不会出现线程间的绑定错误。

             private QueuedBackgroundWorker worker;


            
    public Form1()
            {
                InitializeComponent();

                worker 
    = new QueuedBackgroundWorker();
                worker.IsBackground 
    = true;
                worker.Threads 
    = 1;
                worker.ProcessingMode 
    = ProcessingMode.FIFO;
                worker.DoWork 
    += new QueuedWorkerDoWorkEventHandler(worker_DoWork);
                worker.RunWorkerCompleted 
    += new RunQueuedWorkerCompletedEventHandler(worker_RunWorkerCompleted);
            }

            
            
    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
            {
                worker.DoWork 
    -= worker_DoWork;
                worker.RunWorkerCompleted 
    -= worker_RunWorkerCompleted;
                worker.Dispose();
            }

            
    private void GetVerifyImage()
            {
                worker.RunWorkerAsync(
    "GetImage");
            }

            
    void worker_DoWork(object sender, QueuedWorkerDoWorkEventArgs e)
            {
                
    string newverifyUrl = "http://captcha.qq.com/getimage?aid=1007901&0.5723910723542236";
                
    string referer = "http://reg.qq.com";

                cookieReg 
    = new CookieContainer();
                HttpHelper httpHelper 
    = new HttpHelper();
                
    using (Stream s = httpHelper.GetStream(newverifyUrl, cookieReg, referer))
                {
                    
    if (s == null)
                    {
                        MessageUtil.ShowWarning(
    "获取登陆码错误,请检查您的网络!");
                        
    return;
                    }
                    e.Result 
    = Image.FromStream(s);
                }
            }

            
    void worker_RunWorkerCompleted(object sender, QueuedWorkerCompletedEventArgs e)
            {
                Image image 
    = e.Result as Image;
                
    if (image != null)
                {
                    
    this.pictureBox1.Image = image;
                }
            }

     线程封装类的源码地址提供给大家下载:https://files.cnblogs.com/wuhuacong/QueuedBackgroundWorker.rar

     其实用C#内置的后台线程也是可以处理这个问题的,只是这个封装的后台线程,提供较好的一些封装及处理,可以应付更为复杂的情况,而对于要等线程返回值、用户可取消的操作,更是方便。系统这些对你有帮助!

    主要研究技术:代码生成工具、会员管理系统、客户关系管理软件、病人资料管理软件、Visio二次开发、酒店管理系统、仓库管理系统等共享软件开发
    专注于Winform开发框架/混合式开发框架Web开发框架Bootstrap开发框架微信门户开发框架的研究及应用
      转载请注明出处:
    撰写人:伍华聪  http://www.iqidi.com 
        
  • 相关阅读:
    SQLite的sqlite_sequence表
    缓存区溢出漏洞工具Doona
    SQLite的sqlite_master表
    dfs1321
    三维bfs(HUD1253胜利大逃亡)
    dfs模版
    poj3259: Wormholes(BF模板题)
    Bellman-Ford算法
    POJ1611:The Suspects(模板题)
    poj3126
  • 原文地址:https://www.cnblogs.com/wuhuacong/p/1870413.html
Copyright © 2011-2022 走看看