如何在运行时更新数据源时避免控件冻结?

时间:2017-02-14 14:43:20

标签: c# winforms datagridview freeze

我在WinForms应用程序中工作,并在我的应用程序中使用DataGridView控件。最初,我已经加载了10000行和50列。我的方案是以特定时间间隔更新数据源(使用Timer)。

问题:在更新数据源时执行操作(cell_click,滚动等)时网格已被冻结/帮派。

如何解决此问题?有没有解决方法?请建议你的想法。

到目前为止,这是我的代码:

private void timer1_Tick(object sender, EventArgs e)
    {
        //try
        {
            timer.Stop();
            for (int i = 0; i < 10000; i++)
            {
                var row = r.Next() % 10000;
                for (int col = 1; col < 10; col++)
                {
                    var colNum = r.Next() % 55;
                    if (table != null)
                        table.Rows[row][colNum] = "hi";// r.Next().ToString();
                }
            }
            table.AcceptChanges();
            timer.Start();
        }
    }

以下是示例输出:

[https://drive.google.com/open?id=0B9MOGv1FOt-TQ1BNZWtnRktxeXc]

感谢。

2 个答案:

答案 0 :(得分:1)

其中一个解决方案是在长时间运行期间调用Application.DoEvents()。这是样本

private void timer1_Tick(object sender, EventArgs e)
{
    //try
    {
        timer.Stop();
        for (int i = 0; i < 10000; i++)
        {
            var row = r.Next() % 10000;
            for (int col = 1; col < 10; col++)
            {
                var colNum = r.Next() % 55;
                if (table != null)
                    table.Rows[row][colNum] = "hi";// r.Next().ToString();
            }
            Application.DoEvents(); //add this line
        }
        table.AcceptChanges();
        timer.Start();
    }
}

另一种解决方案是将长时间运行的任务移到单独的线程中。

答案 1 :(得分:0)

尝试使用BackgrounWorker。

  

BackgroundWorker是System.ComponentModel中的辅助类   用于管理工作线程的命名空间。它可以被认为是   EAP(基于事件的异步模式)的通用实现,并提供以下内容   特性:

     
      
  • 合作取消模式

  •   
  • 工作人员完成时安全更新WPF或Windows窗体控件的能力

  •   
  • 转发完成事件的例外
  •   
  • 报告进度的协议
  •   
  • IComponent的一个实现,允许它位于Visual Studio的设计器中
  •   

Bellow你可以找一个例子,请调整你的计时器:

class Program
{
  static BackgroundWorker _bw = new BackgroundWorker();

  static void Main()
  {
    _bw.DoWork += bw_DoWork;
    _bw.RunWorkerAsync ("Message to worker");
    Console.ReadLine();
  }

  static void bw_DoWork (object sender, DoWorkEventArgs e)
  {
    // This is called on the worker thread
    Console.WriteLine (e.Argument);        // writes "Message to worker"
    // Perform time-consuming task...


           //update your grid
            for (int i = 0; i < 10000; i++)
            {
                var row = r.Next() % 10000;
                for (int col = 1; col < 10; col++)
                {
                    var colNum = r.Next() % 55;
                    if (table != null)
                        table.Rows[row][colNum] = "hi";r.Next().ToString();
                }
            }
            table.AcceptChanges();

  }
}