You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# WinForms百万级数据网格增量搜索性能优化咨询

问题描述

我开发了一个基于C#的Windows Forms应用,需实现文本框对网格控件的增量搜索功能。当前数据量达300万条,输入字符时应用会卡顿6秒才能完成过滤显示。

我目前使用以下代码进行网格过滤:

private void textBox1_TextChanged(object sender, EventArgs e)
{
    string searchValue = textBox1.Text.Trim().ToLower();
    if (string.IsNullOrEmpty(searchValue))
    {
        dataGrid1.DataSource = dataTable;
    }
    else
    {
        var filteredRows = dataTable.AsEnumerable()
            .Where(row => row.ItemArray.Any(
                field => field.ToString().ToLower().Contains(searchValue)));

        if (filteredRows.Any())
        {
            dataGrid1.DataSource = filteredRows.CopyToDataTable();
        }
        else
        {
            dataGrid1.DataSource = dataTable.Clone(); // No matches, clear grid
        }
    }
}

更新:我尝试了以下代码,耗时有所缩短但仍无法实现实时过滤:

(dataGrid1.DataSource as DataTable).DefaultView.RowFilter= string.Format("Name LIKE '%{0}%'", searchValue);

请问有什么方法可以提升增量搜索的速度?


优化方案

1. 防抖处理(减少无效触发)

文本框每输入一个字符就触发一次过滤,300万条数据下频繁执行会直接导致卡顿。给搜索加个延迟,等用户停止输入500ms左右再执行过滤:

private Timer _searchTimer;

// 在Form_Load里初始化Timer
private void Form_Load(object sender, EventArgs e)
{
    _searchTimer = new Timer();
    _searchTimer.Interval = 500;
    _searchTimer.Tick += (s, e) =>
    {
        _searchTimer.Stop();
        PerformSearch(textBox1.Text.Trim().ToLower());
    };
}

private void textBox1_TextChanged(object sender, EventArgs e)
{
    _searchTimer.Stop();
    _searchTimer.Start();
}

private void PerformSearch(string searchValue)
{
    var view = dataGrid1.DataSource as DataView;
    if (string.IsNullOrEmpty(searchValue))
    {
        view.RowFilter = "";
    }
    else
    {
        view.RowFilter = $"Name LIKE '%{searchValue}%'";
    }
}

2. 预索引与缓存优化

避免每次过滤都重复执行ToString().ToLower()这类耗时操作,提前缓存目标字段的处理结果:

private List<string> _nameCache;
private DataView _originalView;

// 初始化时缓存数据
private void InitData()
{
    _originalView = new DataView(dataTable);
    _originalView.Sort = "Name"; // 排序会自动创建索引,加速后续过滤
    dataGrid1.DataSource = _originalView;
    
    // 提前缓存Name字段的小写值
    _nameCache = dataTable.AsEnumerable()
                          .Select(row => row["Name"].ToString().ToLower())
                          .ToList();
}

private void PerformSearch(string searchValue)
{
    if (string.IsNullOrEmpty(searchValue))
    {
        _originalView.RowFilter = "";
        return;
    }
    
    // 先在缓存列表里找匹配项,再映射回行
    var matchingIndices = _nameCache.Select((name, idx) => new { name, idx })
                                   .Where(x => x.name.Contains(searchValue))
                                   .Select(x => x.idx)
                                   .ToList();
                                   
    var filteredTable = dataTable.Clone();
    foreach (var idx in matchingIndices)
    {
        filteredTable.ImportRow(dataTable.Rows[idx]);
    }
    dataGrid1.DataSource = filteredTable;
}

3. 异步过滤(不阻塞UI)

把过滤逻辑放到后台线程执行,避免UI线程被卡死:

private async void PerformSearch(string searchValue)
{
    dataGrid1.Enabled = false; // 可选:防止用户中途操作
    DataTable resultTable = null;

    // 后台执行过滤
    await Task.Run(() =>
    {
        if (string.IsNullOrEmpty(searchValue))
        {
            resultTable = dataTable.Copy();
        }
        else
        {
            var filteredRows = dataTable.AsEnumerable()
                .Where(row => row["Name"].ToString().ToLower().Contains(searchValue));
            resultTable = filteredRows.Any() ? filteredRows.CopyToDataTable() : dataTable.Clone();
        }
    });

    // 回到UI线程更新数据源
    dataGrid1.DataSource = resultTable;
    dataGrid1.Enabled = true;
}

4. 限制最小搜索长度

设置只有输入字符≥2个时才执行过滤,减少短字符时的全表扫描压力:

private void textBox1_TextChanged(object sender, EventArgs e)
{
    _searchTimer.Stop();
    string searchValue = textBox1.Text.Trim().ToLower();
    
    if (searchValue.Length < 2)
    {
        _originalView.RowFilter = "";
        return;
    }
    
    _searchTimer.Start();
}

5. 更换高性能网格控件

如果内置DataGridView性能跟不上,可以考虑用第三方控件,比如DevExpress GridControl、Telerik RadGridView,这类控件自带虚拟滚动、优化过滤机制,对大数据量的支持远好于原生控件。


内容的提问来源于stack exchange,提问作者zac

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 00:50:10