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

How to avoid the control gets freeze while updating the datasource at runtime?

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

问题: 在更新数据源时执行操作(cell_click、滚动等)时,网格已 frozen/gang。

如何解决这个问题?有什么解决方法吗?请提出您的想法。

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

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]

谢谢。

其中一个解决方案是在如此长的 运行 操作期间调用 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();
    }
}

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

尝试使用 BackgroundWorker。

BackgroundWorker is a helper class in the System.ComponentModel namespace for managing a worker thread. It can be considered a general-purpose implementation of the EAP(The Event-Based Asynchronous Pattern), and provides the following features:

  • A cooperative cancellation model

  • The ability to safely update WPF or Windows Forms controls when the worker completes

  • Forwarding of exceptions to the completion event
  • A protocol for reporting progress
  • An implementation of IComponent allowing it to be sited in Visual Studio’s designer

您可以在下面找到示例,请根据您的计时器进行调整:

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();

  }
}