【问题标题】:C# Why is this loop so slow?C# 为什么这个循环这么慢?
【发布时间】:2009-06-07 23:49:52
【问题描述】:

我继承了一些将过滤器应用于数据网格的代码,过滤器适用于但当数据网格中有 500 多行时非常慢(它挂起超过 500 行,适用于 100 行),过滤器基本上说“给我看所有付款的人”或“给我看 X 国家的每个人”等。

立即创建与过滤器匹配的行列表(下面的 filteredRows)。

        if (comboBoxFilterCondition.Text == "Contains")
        {
            strSearchFilter += string.IsNullOrEmpty(txtFilterValue.Text) ? " IS NULL" : " LIKE '%" + txtFilterValue.Text + "%'";
        }

        FilterRows(strSearchFilter);

//....

    private void FilterRows(string strSearchFilter)
    {
            DataTable table = dataGridView1.DataSource as DataTable;
            if (table != null)
            {
                List<DataRow> filteredRows = new List<DataRow>(table.Select(strSearchFilter)); //<----Very quick to here

                CurrencyManager cm = (CurrencyManager)BindingContext[dataGridView1.DataSource];
                cm.SuspendBinding();
                foreach (DataGridViewRow row in dataGridView1.Rows)
                {
                    row.Visible = filteredRows.Contains(((DataRowView)row.DataBoundItem).Row); //<---Stuck here
                }
                cm.ResumeBinding(); //<----------Doesn't arrive here

//..... }

有什么想法吗? 谢谢大家

【问题讨论】:

    标签: c# datagrid


    【解决方案1】:

    没有理由自己进行过滤。如果 datagridview 绑定到 DataTable(看起来确实如此),只需使用 DataTable.DefaultView.RowFilter 属性。样品来了...

    好的,我创建了一个带有 DataGridView 和两个按钮的简单表单。在第一个按钮上单击它会应用一个数据表,在第二个按钮上它会过滤它:

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
    
        private void button1_Click(object sender, EventArgs e)
        {
            DataTable table = new DataTable();
            table.Columns.Add("Name", typeof(string));
            table.Columns.Add("Age", typeof(int));
            table.Rows.Add("John", 25);
            table.Rows.Add("Jack", 34);
            table.Rows.Add("Mike", 17);
            table.Rows.Add("Mark", 54);
            table.Rows.Add("Frank", 37);
    
            this.dataGridView1.DataSource = table;
        }
    
        private void button2_Click(object sender, EventArgs e)
        {
            var table = this.dataGridView1.DataSource as DataTable;
            table.DefaultView.RowFilter = "Age > 30";
    
        }
    

    当您单击第二个按钮时,网格将被自动过滤。这应该比自己手动完成要快得多。请查看我之前向您展示的链接以及此链接:http://msdn.microsoft.com/en-us/library/system.data.datacolumn.expression.aspx,了解有关构建过滤器表达式的更多信息。

    【讨论】:

    • 我不建议使用默认视图...您可能需要在其他地方隐藏数据,如果您这样做,它不会出现在默认视图中。我认为最好在表上创建一个新的 DataView。否则,好的答案,我投赞成票;)
    【解决方案2】:

    它可能很慢的原因是,每次调用 Contains 方法时,它都必须遍历 filterRows 列表中的所有行,直到找到您要查找的行。这意味着您每次通过循环可能会循环多达 500 次。

    BFree 有关于如何解决问题的正确答案。但是,我要补充一点,如果您将多个事物绑定到表,则可以改为绑定到 BindingSource。绑定源具有您可以设置的过滤器属性。

    【讨论】:

      【解决方案3】:

      我最好的猜测是它与比较两个 DataRow 实例的方式有关。换个试试

      List<DataRow> filteredRows = new List<DataRow>(table.Select(strSearchFilter));
      

      HashSet<DataRow> filteredRows = new HashSet<DataRow>(table.Select(strSearchFilter));
      

      【讨论】:

      • Hashset 在 .net 3.5 中吗?我正在使用.net 2.0。谢谢
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多