zoukankan      html  css  js  c++  java
  • 异步处理与界面交互

    当我们读取一个大数据量的数据表的时候,如果采用直接读的方式,很容易造成界面成为“白板”的现象,这也是所谓的假死。这种方式并不是十分好,因为它不能让用户非常直观的看到界面(比如加入进度条显示进度),所以需要有一种手段来防止这种现象的发生。在.net中,要实现这种方式很容易,我们只要利用BeginInvoke开启异步操作即可。首先是开始前的准备工作,我们往Person表中插入一百万数据作为测试数据:

    declare 
    @countint,
    @endint;
    begin
    select@count=1000000;
    select@end=0;
    while@count>@end
    insertinto Person(PER_FIRST_NAME,PER_Last_NAME,PER_BIRTH_DATE,PER_WEIGHT_KG,PER_HEIGHT_M)
    values('11111','2222222',GETDATE(),34,45)
    set@count=@count-1
    end

    然后就是全部的操作代码,我坐上了详细的注释:

    using System;
    using System.Data;
    using System.Data.SqlClient;
    using System.Windows.Forms;
    using System.Runtime.Remoting.Messaging;

    namespace ReadBigDataFromOracle
    {
    publicpartialclass MainFrm : Form
    {
    public MainFrm()
    {
    InitializeComponent();
    }

    privatedelegate DataTable GetDataFromDataBaseDelegate(); //申明委托
    privatestaticstring connStr ="server=.;uid=sa;pwd=251147;database=iBatisDemo;";

    //从数据库提取大数据量的数据,这里是造成界面假死的原因
    private DataTable GetDataBaseLog()
    {
    string sql ="select * from Person";
    DataTable dt
    =new DataTable();

    using (SqlConnection conn =new SqlConnection(connStr))
    {
    conn.Open();
    SqlCommand cmd
    =new SqlCommand(sql, conn);
    SqlDataAdapter sda
    =new SqlDataAdapter(cmd);
    sda.Fill(dt);
    }
    return dt; //返回填充好的数据集对象
    }

    //回调函数,这里处理异步回调
    privatevoid BindDataToListBoxCallBack(IAsyncResult iar)
    {
    AsyncResult result
    = (AsyncResult)iar;
    GetDataFromDataBaseDelegate getDataDelegate
    = (GetDataFromDataBaseDelegate)result.AsyncDelegate; //得到委托对象

    DataTable dt
    = getDataDelegate.EndInvoke(iar); //得到异步处理的结果

    if (this.lsbData.InvokeRequired) //如果出现线程和界面交互
    {
    this.Invoke(new MethodInvoker(delegate()
    {
    BindListBox(dt);
    //绑定数据到ListBox
    }
    ));
    }
    else
    {
    BindListBox(dt);
    //反之直接绑定
    }
    }

    privatevoid BindListBox(DataTable dt)
    {
    this.lsbData.DataSource = dt;
    }


    privatevoid MainFrm_Load(object sender, EventArgs e)
    {

    }

    privatevoid btnStart_Click(object sender, EventArgs e)
    {
    //调用对象
    GetDataFromDataBaseDelegate getData =new GetDataFromDataBaseDelegate(GetDataBaseLog);

    //开始进行异步调用
    getData.BeginInvoke(new AsyncCallback(BindDataToListBoxCallBack), null);

    //这里可以干别的事情
    tTick.Enabled =true;
    }

    int iCount =0;
    //这个测试异步处理的时候,做其他事情有没有影响的
    privatevoid tTick_Tick(object sender, EventArgs e)
    {
    ++iCount;
    lblCount.Text
    = iCount.ToString();
    }
    }
    }

    其实这里的执行流程就是:

    首先,利用委托对象获取要执行的方法

    然后,调用委托的BeginInvoke方法来开始异步执行。

  • 相关阅读:
    (二分查找 拓展) leetcode 69. Sqrt(x)
    (二分查找 拓展) leetcode 162. Find Peak Element && lintcode 75. Find Peak Element
    (链表) lintcode 219. Insert Node in Sorted Linked List
    (二分查找 拓展) leetcode 34. Find First and Last Position of Element in Sorted Array && lintcode 61. Search for a Range
    (最短路 Floyd) P2910 [USACO08OPEN]寻宝之路Clear And Present Danger 洛谷
    (字符串 数组 递归 双指针) leetcode 344. Reverse String
    (二叉树 DFS 递归) leetcode 112. Path Sum
    (二叉树 DFS 递归) leetcode 101. Symmetric Tree
    (二叉树 递归) leetcode 144. Binary Tree Preorder Traversal
    (二叉树 递归 DFS) leetcode 100. Same Tree
  • 原文地址:https://www.cnblogs.com/scy251147/p/2175310.html
Copyright © 2011-2022 走看看