从数据库中读取数据,并在lable中不断刷新显示(类似抽奖的数据滚动)。但timer的Interval已经为1了。可是刷新的速度还是很慢。请问如何才能更快些呢。 timer的tick事件如下:
if (ds.Tables[0].Rows.Count != 0)
{
label2.Text = ds.Tables[0].Rows[i]["id"].ToString(); i++;
}
用的是dataset从数据库中读取数据
if (ds.Tables[0].Rows.Count != 0)
{
label2.Text = ds.Tables[0].Rows[i]["id"].ToString(); i++;
}
用的是dataset从数据库中读取数据
能不能把dataset先缓存起来
{
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();
}
}
if (ds.Tables[0].Rows.Count > i)
吧?timer有好几种,在好几个命名空间中都有,各自实现机制不同。不过这似乎不应该使用 Timer 这么复杂的控制机制。显示功能应该专门独占一个线程,线程方法中两次显示之间使用Sleep(1000) 代码,或者使用一个循环来检测是否距离上次显示的等待时间以及检测其它条件(例如用户有没有触摸其他功能),循环中间 Sleep(100)。
{
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 就是中奖者了
}
}
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
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 等线程间同步的类来设计出同样效果的代码
将显示和读取分析的线程一定要分开。
否则会影响正常的显示。
---------------------------------窝的方法是绝对单线程的,但没显示问题,全靠Application.DoEvents()
for循环,循环中调用Application.DoEvents()。
不过CPU利用率可能会高达100%,你可以Thread.Sleep(1)一下。//当然,你可以等更久点只是,从问题上看似乎应该不是这个原因导致你的label显示不够快。另:恕我直言,你的catch语句写得丑陋无比!(你要明白什么是"异常"。你这是在掩盖"异常",请你不要把"异常"当作一种正常流程。)
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]行的代码会一直抛异常,
// 你就一直重新读数据,重新出错,重新读数据,重新出错……