隐藏

用C#多线程在winform DataGridView简单实现像ajax更新效果

发布:2022/9/15 17:08:15作者:管理员 来源:本站 浏览次数:1692



最近在做一个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来锁定了。