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

C#计算文件夹大小时点击C盘出现7-8秒应用卡顿问题求助

问题根因

当前实现存在两个核心问题直接导致点击C盘时应用冻结:

  • 文件夹大小计算逻辑同步运行在UI线程:FolderModel的构造函数由UI线程触发执行,你在构造函数内直接调用阻塞式的目录遍历逻辑,会直接卡住UI消息循环,直到全盘遍历完成才会恢复响应
  • 全量目录遍历效率极低:GetDirectorySize使用SearchOption.AllDirectories遍历所有子目录,C盘默认存在海量系统文件、受权限保护的隐藏目录(比如System Volume Information、Windows系统目录、用户AppData目录等),文件数量通常是普通数据盘的数倍,遍历耗时自然达到7-8秒甚至更久

排查验证思路

  • 给GetDirectorySize方法增加耗时、遍历文件数日志,确认阻塞是否由遍历C盘的高耗时导致
  • 点击C盘时查看任务管理器中应用的CPU、磁盘IO占用,确认是否处于满负载遍历状态
  • 单独测试遍历C盘下不同子目录的耗时,定位是否是特定系统目录的权限异常、大量小文件拖慢了整体速度

解决方案

1. 把同步计算改成异步非阻塞计算

不要在FolderModel构造函数中同步计算大小,构造时先显示*计算中...*占位符,后台异步计算完成后再更新UI:

// 改造示例,基于WPF的INotifyPropertyChanged实现
public string FolderSize 
{
    get => _folderSize;
    set { _folderSize = value; OnPropertyChanged(); }
}
private string _folderSize = "计算中...";

public FolderModel(string folderPath)
{
    // 原有初始化逻辑保留
    FolderInfo = new DirectoryInfo(folderPath);
    _folderName = FolderInfo.Name;
    _folderPath = folderPath;
    this.Children = new ObservableCollection<FolderModel>();
    
    // 异步启动大小计算,不阻塞构造函数和UI线程
    _ = CalculateFolderSizeAsync(folderPath);
}

private async Task CalculateFolderSizeAsync(string folderPath)
{
    long totalSize = await Task.Run(() => GetDirectorySize(folderPath));
    // 计算完成后切回UI线程更新显示
    Application.Current.Dispatcher.Invoke(() => 
    {
        FolderSize = CalculatorSize(totalSize);
    });
}

2. 优化目录遍历逻辑降低耗时

  • 取消SearchOption.AllDirectories全量遍历,改成按需层级计算:默认只统计当前目录第一层的文件大小,子目录大小等用户点击展开对应节点时再计算,不需要打开C盘就遍历全盘
  • 增加系统目录过滤:默认跳过System Volume Information、$Recycle.Bin、Windows、Program Files等权限受限的系统目录,避免无意义的权限异常和遍历消耗
  • 遍历前判断目录属性,标记为Hidden+System的目录默认跳过,减少无效遍历

3. 增加缓存机制

将已经计算完成的文件夹大小存入本地缓存,下次访问同一个目录时直接读取缓存结果,不需要重复遍历,仅监听目录文件变更事件,目录有修改时才触发重新计算。

4. 优化异常处理

你当前代码直接吞掉了所有异常,建议增加日志记录访问失败的目录,方便后续调整过滤规则,也能及时发现潜在的遍历异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 01:06:06