dataGridView 界面逐行刷新,速度过慢?急急急!!!

clwk 2016-12-15 05:42:52
写了一个工具,界面是dataGridView,大概有500行数据。
dataGridView的用途是500行数据全部初始化填充完毕,每行是一个要运行的任务。运行成功,则设置此行颜色为绿色,失败为红色。
我遇到的问题是:
目前只单独实现了逐行刷新颜色的操作,但是发现逐行刷新界面的速度非常慢。(实际上应该是非常快的刷新完毕)
但是如果最小化一下,再恢复,就马上刷新完毕所有行。或者不用线程,速度也奇快。。。
请教一下,该如何解决这个问题。
代码大概如下:通过启动DoWork线程来做刷新操作。

workerThread = new Thread(worker.DoWork);
workerThread.IsBackground = true;
workerThread.Start();


public void DoWork()
{
for (int i = 0; i < 500; i++)
{
SetTestResult(i,Color.red);
}
}

public void SetTestResult(int Index,Color color)
{
dataGridView_DbgWindow[0, Index].Style.BackColor = color;
dataGridView_DbgWindow[1, Index].Style.BackColor = color;
dataGridView_DbgWindow[2, Index].Style.BackColor = color;
dataGridView_DbgWindow[3, Index].Style.BackColor = color;
dataGridView_DbgWindow[4, Index].Style.BackColor = color;
}
...全文
1440 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
bigbaldy 2016-12-16
  • 打赏
  • 举报
回复
不知道为何你会慢,我这测试5000个都是瞬间完成,测试环境:i5 4570+8G+win10-64bit+.net framework4.5.2

public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            List<int> list = new List<int>();
            for (int i = 0; i < 5000; i++)
            {
                list.Add(i);
            }
            dataGridView_DbgWindow.DataSource = list;
            Task.Run(() =>
            {
                for (int i = 0; i < 5000; i++)
                {
                    SetTestResult(i, Color.Red);
                }
            }); 
        }

        public void SetTestResult(int Index, Color color)
        {
            dataGridView_DbgWindow[0, Index].Style.BackColor = color;
            dataGridView_DbgWindow[1, Index].Style.BackColor = color;
            dataGridView_DbgWindow[2, Index].Style.BackColor = color;
            dataGridView_DbgWindow[3, Index].Style.BackColor = color;
            dataGridView_DbgWindow[4, Index].Style.BackColor = color;
        }
    }
xinweilee 2016-12-16
  • 打赏
  • 举报
回复
dataGridView_DbgWindow..Rows[Index].DefaultCellStyle.BackColor = color; dataGridView_DbgWindow..InvalidateRow(Index);试一下 楼主的示例也是很慢的吗?还是说你的实际程序中慢
clwk 2016-12-16
  • 打赏
  • 举报
回复
引用 2 楼 daixf_csdn 的回复:
1、跨线程改变UI应该用BeginInvoke 2、修改时禁止刷新,修改完一次性刷新。即SuspendLayout和ResumeLayout
感谢回复。 我在每次都加了,还是没有改善。 public void SetTestResult(int Index,Color color) { if (dataGridView_DbgWindow.InvokeRequired) { SetTestResultDelegate dl = new SetTestResultDelegate(SetTestResult); this.Invoke(dl, new object[] { Index, color }); } dataGridView_DbgWindow.SuspendLayout(); dataGridView_DbgWindow[0, Index].Style.BackColor = color; dataGridView_DbgWindow[1, Index].Style.BackColor = color; dataGridView_DbgWindow[2, Index].Style.BackColor = color; dataGridView_DbgWindow[3, Index].Style.BackColor = color; dataGridView_DbgWindow[4, Index].Style.BackColor = color; dataGridView_DbgWindow.ResumeLayout(); }
clwk 2016-12-16
  • 打赏
  • 举报
回复
引用 2 楼 daixf_csdn 的回复:
1、跨线程改变UI应该用BeginInvoke 2、修改时禁止刷新,修改完一次性刷新。即SuspendLayout和ResumeLayout
多谢回复。 请问一下,这个是要对mainform操作,还是对datagridview操作的?
引用 9 楼 stherix 的回复:
[quote=引用 7 楼 clwk 的回复:] [quote=引用 5 楼 stherix 的回复:] [quote=引用 3 楼 clwk 的回复:] [quote=引用 1 楼 stherix 的回复:] 虽然你在线程里设置了值 但是Grid界面没有重画 所以要Invalidate一下
多谢回复。 我在下面加了,但是好像没有效果,另,我这个是datagridview,应该和gridview也是一样的吧。 public void SetTestResult(int Index,Color color) { dataGridView_DbgWindow[0, Index].Style.BackColor = color; dataGridView_DbgWindow[1, Index].Style.BackColor = color; dataGridView_DbgWindow[2, Index].Style.BackColor = color; dataGridView_DbgWindow[3, Index].Style.BackColor = color; dataGridView_DbgWindow[4, Index].Style.BackColor = color; dataGridView_DbgWindow.Invalidate(); }[/quote] 在线程中改变界面 需要用Invoke 另外Invalidate再循环外执行一次就行了,不然频繁刷新 会造成性能低下 [/quote] [/quote] 是加在这里吗? public void DoWork() { for (int i = 0; i < 500; i++) { SetTestResult(i,Color.red); } dataGridView_DbgWindow.Invalidate(); } 设置之后,再用Invalidate刷新[/quote] 我这个是按行实时刷新行的,加在最后,对这个刷新满的问题没有改善。
stherix 2016-12-16
  • 打赏
  • 举报
回复
引用 7 楼 clwk 的回复:
[quote=引用 5 楼 stherix 的回复:] [quote=引用 3 楼 clwk 的回复:] [quote=引用 1 楼 stherix 的回复:] 虽然你在线程里设置了值 但是Grid界面没有重画 所以要Invalidate一下
多谢回复。 我在下面加了,但是好像没有效果,另,我这个是datagridview,应该和gridview也是一样的吧。 public void SetTestResult(int Index,Color color) { dataGridView_DbgWindow[0, Index].Style.BackColor = color; dataGridView_DbgWindow[1, Index].Style.BackColor = color; dataGridView_DbgWindow[2, Index].Style.BackColor = color; dataGridView_DbgWindow[3, Index].Style.BackColor = color; dataGridView_DbgWindow[4, Index].Style.BackColor = color; dataGridView_DbgWindow.Invalidate(); }[/quote] 在线程中改变界面 需要用Invoke 另外Invalidate再循环外执行一次就行了,不然频繁刷新 会造成性能低下 [/quote] [/quote] 是加在这里吗? public void DoWork() { for (int i = 0; i < 500; i++) { SetTestResult(i,Color.red); } dataGridView_DbgWindow.Invalidate(); } 设置之后,再用Invalidate刷新
clwk 2016-12-16
  • 打赏
  • 举报
回复
引用 4 楼 u012948520 的回复:
线程操作界面不用invoke也没报错吗? 改变之后要不要加一个refresh之类的呢?
有Invoke的,忘了贴上了。
clwk 2016-12-16
  • 打赏
  • 举报
回复
引用 5 楼 stherix 的回复:
[quote=引用 3 楼 clwk 的回复:] [quote=引用 1 楼 stherix 的回复:] 虽然你在线程里设置了值 但是Grid界面没有重画 所以要Invalidate一下
多谢回复。 我在下面加了,但是好像没有效果,另,我这个是datagridview,应该和gridview也是一样的吧。 public void SetTestResult(int Index,Color color) { dataGridView_DbgWindow[0, Index].Style.BackColor = color; dataGridView_DbgWindow[1, Index].Style.BackColor = color; dataGridView_DbgWindow[2, Index].Style.BackColor = color; dataGridView_DbgWindow[3, Index].Style.BackColor = color; dataGridView_DbgWindow[4, Index].Style.BackColor = color; dataGridView_DbgWindow.Invalidate(); }[/quote] 在线程中改变界面 需要用Invoke 另外Invalidate再循环外执行一次就行了,不然频繁刷新 会造成性能低下 [/quote] 是加在这里吗? public void DoWork() { dataGridView_DbgWindow.Invalidate(); for (int i = 0; i < 500; i++) { SetTestResult(i,Color.red); } }
clwk 2016-12-16
  • 打赏
  • 举报
回复
里面加了Invoke了。 public void SetTestResult(int Index,Color color) { if (dataGridView_DbgWindow.InvokeRequired) { SetTestResultDelegate dl = new SetTestResultDelegate(SetTestResult); this.Invoke(dl, new object[] { Index, color }); } dataGridView_DbgWindow[0, Index].Style.BackColor = color; dataGridView_DbgWindow[1, Index].Style.BackColor = color; dataGridView_DbgWindow[2, Index].Style.BackColor = color; dataGridView_DbgWindow[3, Index].Style.BackColor = color; dataGridView_DbgWindow[4, Index].Style.BackColor = color; dataGridView_DbgWindow.Invalidate(); }
stherix 2016-12-16
  • 打赏
  • 举报
回复
引用 3 楼 clwk 的回复:
[quote=引用 1 楼 stherix 的回复:] 虽然你在线程里设置了值 但是Grid界面没有重画 所以要Invalidate一下
多谢回复。 我在下面加了,但是好像没有效果,另,我这个是datagridview,应该和gridview也是一样的吧。 public void SetTestResult(int Index,Color color) { dataGridView_DbgWindow[0, Index].Style.BackColor = color; dataGridView_DbgWindow[1, Index].Style.BackColor = color; dataGridView_DbgWindow[2, Index].Style.BackColor = color; dataGridView_DbgWindow[3, Index].Style.BackColor = color; dataGridView_DbgWindow[4, Index].Style.BackColor = color; dataGridView_DbgWindow.Invalidate(); }[/quote] 在线程中改变界面 需要用Invoke 另外Invalidate再循环外执行一次就行了,不然频繁刷新 会造成性能低下
白衣如花 2016-12-16
  • 打赏
  • 举报
回复
线程操作界面不用invoke也没报错吗? 改变之后要不要加一个refresh之类的呢?
clwk 2016-12-16
  • 打赏
  • 举报
回复
引用 1 楼 stherix 的回复:
虽然你在线程里设置了值 但是Grid界面没有重画 所以要Invalidate一下
多谢回复。 我在下面加了,但是好像没有效果,另,我这个是datagridview,应该和gridview也是一样的吧。 public void SetTestResult(int Index,Color color) { dataGridView_DbgWindow[0, Index].Style.BackColor = color; dataGridView_DbgWindow[1, Index].Style.BackColor = color; dataGridView_DbgWindow[2, Index].Style.BackColor = color; dataGridView_DbgWindow[3, Index].Style.BackColor = color; dataGridView_DbgWindow[4, Index].Style.BackColor = color; dataGridView_DbgWindow.Invalidate(); }
圣殿骑士18 2016-12-16
  • 打赏
  • 举报
回复
1、跨线程改变UI应该用BeginInvoke 2、修改时禁止刷新,修改完一次性刷新。即SuspendLayout和ResumeLayout
clwk 2016-12-16
  • 打赏
  • 举报
回复
引用 12 楼 xinweilee 的回复:
dataGridView_DbgWindow..Rows[Index].DefaultCellStyle.BackColor = color; dataGridView_DbgWindow..InvalidateRow(Index);试一下 楼主的示例也是很慢的吗?还是说你的实际程序中慢
这个我试过, 这种方式,行的颜色没有变化。所以pass掉了。不得不选择现在的方式。
clwk2000 2016-12-16
  • 打赏
  • 举报
回复
引用 13 楼 bigbaldy 的回复:
不知道为何你会慢,我这测试5000个都是瞬间完成,测试环境:i5 4570+8G+win10-64bit+.net framework4.5.2

public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            List<int> list = new List<int>();
            for (int i = 0; i < 5000; i++)
            {
                list.Add(i);
            }
            dataGridView_DbgWindow.DataSource = list;
            Task.Run(() =>
            {
                for (int i = 0; i < 5000; i++)
                {
                    SetTestResult(i, Color.Red);
                }
            }); 
        }

        public void SetTestResult(int Index, Color color)
        {
            dataGridView_DbgWindow[0, Index].Style.BackColor = color;
            dataGridView_DbgWindow[1, Index].Style.BackColor = color;
            dataGridView_DbgWindow[2, Index].Style.BackColor = color;
            dataGridView_DbgWindow[3, Index].Style.BackColor = color;
            dataGridView_DbgWindow[4, Index].Style.BackColor = color;
        }
    }
非常感谢回复。 如果不是在Thread里面用,我也试过,是秒完的。 所以这也是我的困惑。
stherix 2016-12-15
  • 打赏
  • 举报
回复
虽然你在线程里设置了值 但是Grid界面没有重画 所以要Invalidate一下

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧