从数据库中读取数据,并在lable中不断刷新显示(类似抽奖的数据滚动)。但timer的Interval已经为1了。可是刷新的速度还是很慢。请问如何才能更快些呢。 timer的tick事件如下:
if (ds.Tables[0].Rows.Count != 0) 
                {
                    label2.Text = ds.Tables[0].Rows[i]["id"].ToString();                    i++;
                }
用的是dataset从数据库中读取数据

解决方案 »

  1.   

    那要怎么才快点?我把数据一次性读到dataset,然后从dataset中逐条读取
      

  2.   

    读取数据库要花时间的 
    能不能把dataset先缓存起来
      

  3.   

    public partial class Form1 : Form
        {
            DataBase db = new DataBase();
            
            string ConnStr = "server=127.0.0.1;uid=sa;pwd=44545;database=45
           SqlConnection sc ;
            SqlDataAdapter sda;
            DataSet ds=new DataSet ();
            int i = 0;        public Form1()
            {
                InitializeComponent();
            }
          
                   private void button1_Click(object sender, EventArgs e)
            {
                sc = new SqlConnection(ConnStr);
                sc.Open();
                sda = new SqlDataAdapter("select id from jjj", sc);            sda.Fill(ds);
                
                timer1.Start();
               
            }        private void timer1_Tick(object sender, EventArgs e)
            {
                
              
                try
                {
                    if ((ds.Tables[0].Rows.Count != 0) || (ds.Tables[0].Rows.Count < i))
                    {
                        label2.Text = ds.Tables[0].Rows[i]["id"].ToString();                    i++;
                    }
                }
                catch (Exception)
                {
                    sc = new SqlConnection(ConnStr);
                    sc.Open();
                    sda = new SqlDataAdapter("select id from jjj", sc);                sda.Fill(ds);
                    timer1.Start();
                    
                }
                
              
    }
      

  4.   

    应该是 
      if (ds.Tables[0].Rows.Count > i)
    吧?timer有好几种,在好几个命名空间中都有,各自实现机制不同。不过这似乎不应该使用 Timer 这么复杂的控制机制。显示功能应该专门独占一个线程,线程方法中两次显示之间使用Sleep(1000) 代码,或者使用一个循环来检测是否距离上次显示的等待时间以及检测其它条件(例如用户有没有触摸其他功能),循环中间 Sleep(100)。
      

  5.   

    嫌Timer不够快的话……就要小心CPU了,来:bool rolling;private void button1_Click(object sender, EventArgs e)
    {
        if (rolling)
        {
            rolling = false;
        }
        else
        {
            string[] numbers = new string[1000];
            int pos = 0;
            // 这里我是模拟填充,你当然用的是真的DataTable:
            Random rand = new Random();
            for (int i = 0; i < 1000; i++)
                numbers[i] = rand.Next(100000000, 1000000000).ToString();
            // 开始抽奖吧:
            rolling = true;
            while (rolling == true)
            {
                label1.Text = numbers[pos++];
                if (pos == numbers.Length) pos = 0;
                // 这一句会给时间UI更新其画面和给时间用户中止滚动
                // 当然你的情况更可能是由另一个Timer负责几秒之后自动中止
                Application.DoEvents();
            }
            // 到达这里的话,label1.Text 就是中奖者了
        }
    }
      

  6.   

    --  可以使用多线程来实现,如下:Dim ds As New DataSet
        Dim td As Thread
        Private Sub Form10_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Dim conn As New SqlConnection("Server=localhost;UID=sa;PWD=sa;Database=Northwind")
            Dim cmd As New SqlCommand("select orderID from orders", conn)
            Dim adapter As New SqlDataAdapter(cmd)        adapter.Fill(ds)
        End Sub    '
        '显示子过程
        '
        Private Sub OrderID_Show()
            Dim dr As DataRow        For Each dr In ds.Tables(0).Rows
                lb_Show.Text = dr(0)
                
                '线程Sleep.            Thread.Sleep(100)
            Next
        End Sub    Private Sub btn_Start_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_Start.Click
            
            '初始花一个线程,来执行显示过程.        td = New Thread(New ThreadStart(AddressOf OrderID_Show))        td.Start()
        End Sub    Private Sub btn_Stop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_Stop.Click
            td.Suspend()
        End Sub    Private Sub btn_Resume_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_Resume.Click
            td.Resume()
        End Sub
      

  7.   

    to 楼上:1)听说这里是C#版,不过.NET的语言都是共通的,欢迎来到C#版!
    2)非UI线程直接操作UI线程内的控件属于设计失误
      (即你代码里面的lb_Show.Text = dr(0))
       在.NET 2.0里面会被检测跨线程的内部过程抛异常,请参看:
       http://community.csdn.net/Expert/topic/4895/4895831.xml?temp=.9673731
    3)Thread.Suspend() 和 Thread.Resume() 被定义为过时且不应使用的有潜在危险的技术
       应该应用 lock/Monitor/ReaderWriterLock/Mutex 等线程间同步的类来设计出同样效果的代码
      

  8.   

    ---------------------------------
    将显示和读取分析的线程一定要分开。
    否则会影响正常的显示。
    ---------------------------------窝的方法是绝对单线程的,但没显示问题,全靠Application.DoEvents()
      

  9.   

    嗯,麦的没错。
    for循环,循环中调用Application.DoEvents()。
    不过CPU利用率可能会高达100%,你可以Thread.Sleep(1)一下。//当然,你可以等更久点只是,从问题上看似乎应该不是这个原因导致你的label显示不够快。另:恕我直言,你的catch语句写得丑陋无比!(你要明白什么是"异常"。你这是在掩盖"异常",请你不要把"异常"当作一种正常流程。)
      

  10.   

    To楼主:根据楼上的提示,我发现真正的问题了:
                try
                {
                    if ((ds.Tables[0].Rows.Count != 0) 
         // 上面这句没什么可能为false,只要数据表里面有数据了,就为true
         // 而因为与下一句是用 || 相连,下一句也不会做计算,直接返回结果true
                           || (ds.Tables[0].Rows.Count < i))
                    {
                        label2.Text = ds.Tables[0].Rows[i]["id"].ToString();
         // 然后,你就显示位于 i 的参加者的id,然后递增——但是你没有一个“返回0”的机制
                        i++;
                    }
                }
                catch (Exception)
                {
         // 所以在i超出Rows.Count之后,就会抛异常
         // 然后你在这里重新打开连接读数据
                    sc = new SqlConnection(ConnStr);
                    sc.Open();
                    sda = new SqlDataAdapter("select id from jjj", sc);                sda.Fill(ds);
                    timer1.Start();
         // 但是读完之后你没有把 i 归零
                }
         // 所以前面的读取第[i]行的代码会一直抛异常,
         // 你就一直重新读数据,重新出错,重新读数据,重新出错……