最近在做一个url链接相关的小软件,会用到DataGridView控件和多线程,之前都是在后台开启一个线程,等待线程处理完毕再将数据绑定到DataGridView。这种最后绑定的有失用户检验,但是又不能加一条数据又绑定一次DataGridView,这样效率也太低了。最终选择了用多线程和队列的通过编程形式为DataGridView动态的添加行, 这样就实现了无刷新的实现像网页ajax更新效果。
1、定义Url类
using System;
using System.Collections.Generic;
using System.linq;
using System.Text;
namespace GridDemo
{
public class MUrl
{
public int ID;
public string[] Values;
}
}
2、编写窗体代码
public partial class Form1 : Form
{
Queue<MUrl> dataQueue = new Queue<MUrl>();
private static object locker = new object();
private int urlCompletedCount = 0, urlAllCount;
private bool isQueryCompleted = false;
public Form1()
{
InitializeComponent();
dataGridView1.ColumnCount = 2;
dataGridView1.Columns[0].Name = "ID";
dataGridView1.Columns[1].Name = "Url";
dataGridView1.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
private void button1_Click(object sender, EventArgs e)
{
button1.Enabled = false;
dataQueue.Clear();
urlCompletedCount = 0;
urlAllCount = 0;
isQueryCompleted = false;
dataGridView1.Rows.Clear();
Thread t1 = new Thread(() =>
{
for (int i = 0; i < 100; i++)
{
string[] arrRow = new string[] { i.ToString(), "等待..." };
lock (locker)
{
dataQueue.Enqueue(new MUrl() { ID = i, Values = arrRow });
urlAllCount++;
}
this.Invoke(new MethodInvoker(() =>
{
dataGridView1.Rows.Add(arrRow);
}));
}
isQueryCompleted = true;
});
t1.IsBackground = true;
t1.Start();
Thread t2 = new Thread(() =>
{
while (true)
{
Thread.Sleep(500);
int ID;
if (dataQueue.Count > 0)
{
lock (locker)
{
if (dataQueue.Count > 0)
{
ID = dataQueue.Dequeue().ID;
urlCompletedCount++;
}
else
continue;
}
string url = "http://www.lanhusoft.com/" + ID + ".html";
this.Invoke(new MethodInvoker(() =>
{
if (ID < dataGridView1.Rows.Count)
dataGridView1.Rows[ID].Cells[1].Value = url;
}));
}
else
{
Thread.Sleep(1000);
}
if (isQueryCompleted && urlCompletedCount == urlAllCount)
{
this.Invoke(new MethodInvoker(() =>
{
button1.Enabled = true;
}));
break;
}
}
});
t2.IsBackground = true;
t2.Start();
}
}
线程t1是为DataGridView添加行,线程t2是模拟的一个后台处理功能,这里就是一个简单的拼接url字符串,实际中你可以用比较复杂耗时的逻辑替换。线程t1每增加一行就把数据加入到队列dataQueue中,线程t2就负责从队列中取数据处理之后更新DataGridView的相应行。两个线程同时要对共享队列dataQueue操作,我是通过lock来锁定了。
Copyright © 广州京杭网络科技有限公司 2005-2024 版权所有 粤ICP备16019765号
广州京杭网络科技有限公司 版权所有