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

MAUI(C#)应用加载大体积CSV至DataGrid的优化方案问询

MAUI DataGrid加载大体积CSV数据优化方案

针对20K行以上CSV加载缓慢、UI无响应的问题,结合搜索过滤需求,提供以下优化方案:

一、异步读取CSV,避免UI线程阻塞

同步读取会阻塞UI线程导致卡顿,将CSV读取逻辑放到后台线程执行,完成后再更新UI集合:

private async Task LoadCsvDataAsync(string filePath)
{
    UserDetails.Clear();
    
    // 后台线程处理CSV解析
    var users = await Task.Run(() =>
    {
        var tempList = new List<User>();
        using (TextFieldParser parser = new TextFieldParser(filePath))
        {
            parser.SetDelimiters(",");
            bool firstLine = true;
            while (!parser.EndOfData)
            {
                if (firstLine)
                {
                    firstLine = false;
                    parser.ReadFields();
                    continue;
                }
                string[] rows = parser.ReadFields();
                if (rows == null || rows.Length < 8) continue; // 防止索引越界
                
                tempList.Add(new User
                {
                    EmployeeNo = rows[0],
                    FirstName = rows[4],
                    LastName = rows[3],
                    Location = rows[2],
                    CostCenter = rows[7]
                });
            }
            return tempList;
        }
    });
    
    // 批量添加至UI集合,减少变更通知次数
    foreach (var user in users)
    {
        UserDetails.Add(user);
    }
}

调用方式(替换原同步加载逻辑):

protected override async void OnAppearing()
{
    base.OnAppearing();
    await LoadCsvDataAsync("你的CSV文件路径");
}

二、启用DataGrid UI虚拟化

当前使用的CommunityToolkit.Maui DataGrid支持行/列虚拟化,开启后仅渲染可见区域行,大幅降低内存占用与渲染耗时:

修改XAML中DataGrid属性:

<dg:DataGrid x:Name="myDataGrid"
            ...
            EnableRowVirtualization="True"
            EnableColumnVirtualization="True"
            ...>

三、用ICollectionView实现高效搜索过滤

直接绑定List过滤会遍历全量数据,改用ICollectionView做过滤,支持实时高效筛选:

1. 页面/ViewModel中添加过滤逻辑

private ICollectionView _userDetailsView;
public ICollectionView UserDetailsView
{
    get => _userDetailsView;
    set => SetProperty(ref _userDetailsView, value); // MVVM框架用SetProperty,非MVVM可直接赋值
}

private string _searchText;
public string SearchText
{
    get => _searchText;
    set
    {
        _searchText = value;
        UserDetailsView.Refresh(); // 搜索文本变更时刷新过滤
    }
}

// 初始化集合与视图
UserDetails = new ObservableCollection<User>();
UserDetailsView = CollectionViewSource.GetDefaultView(UserDetails);
UserDetailsView.Filter = FilterUsers;

// 过滤规则
private bool FilterUsers(object item)
{
    if (string.IsNullOrEmpty(SearchText)) return true;
    var user = item as User;
    return user.EmployeeNo.Contains(SearchText, StringComparison.OrdinalIgnoreCase)
           || user.FirstName.Contains(SearchText, StringComparison.OrdinalIgnoreCase)
           || user.LastName.Contains(SearchText, StringComparison.OrdinalIgnoreCase)
           || user.Location.Contains(SearchText, StringComparison.OrdinalIgnoreCase)
           || user.CostCenter.Contains(SearchText, StringComparison.OrdinalIgnoreCase);
}

2. 修改DataGrid绑定源

ItemsSource="{Binding UserDetailsView}"

四、批量添加数据,减少集合变更通知

原代码每添加一条数据触发一次集合变更,20K次通知会导致UI频繁更新。扩展ObservableCollection添加批量插入方法:

public static class ObservableCollectionExtensions
{
    public static void AddRange<T>(this ObservableCollection<T> collection, IEnumerable<T> items)
    {
        foreach (var item in items)
        {
            collection.Add(item);
        }
        // 若需一次性触发通知,可通过反射调用OnCollectionChanged(注意线程安全)
    }
}

替换异步读取后的添加逻辑:

UserDetails.AddRange(users);

五、替换高效CSV解析库(可选)

TextFieldParser性能有限,改用CsvHelper(NuGet安装)提升大文件解析速度:

using CsvHelper;
using System.Globalization;

private async Task LoadCsvDataAsync(string filePath)
{
    UserDetails.Clear();
    
    var users = await Task.Run(() =>
    {
        using var reader = new StreamReader(filePath);
        using var csv = new CsvReader(reader, CultureInfo.InvariantCulture);
        csv.Read();
        csv.ReadHeader();
        
        return csv.GetRecords<dynamic>()
                  .Select(row => new User
                  {
                      EmployeeNo = row[0],
                      FirstName = row[4],
                      LastName = row[3],
                      Location = row[2],
                      CostCenter = row[7]
                  }).ToList();
    });
    
    UserDetails.AddRange(users);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 19:33:20