首页 > 解决方案 > 计算网络驱动器上已用磁盘空间

问题描述

我正在尝试创建一个小工具来检查网络驱动器上已用的磁盘空间。Windows 文件夹属性窗口的行为很奇怪。在检查顶级文件夹时,它显示大约 300 MB 的大小,而有大于 50 Gb 的子文件夹。

文件夹结构:

我已经开始寻找其他方式并找到了这段代码:

    public static long DirSize(DirectoryInfo d)
    {

        long size = 0;
        // Add file sizes.
        FileInfo[] fis = d.GetFiles();
        foreach (FileInfo fi in fis)
        {
            size += fi.Length;
        }
        // Add subdirectory sizes.
        DirectoryInfo[] dis = d.GetDirectories();
        foreach (DirectoryInfo di in dis)
        {
            size += DirSize(di);
        }
        return size;
    }

并尝试以 WPF 形式实现它:

using System.IO;
using System.Windows;

namespace Disk_space_inspector
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            string targetFolder = PathSrc.Text;

            MessageBox.Show ("The size is " + DirSize(new DirectoryInfo(targetFolder)) / 1000000 + " MB.");
        }

        public static long DirSize(DirectoryInfo d)
        {

            long size = 0;
            // Add file sizes.
            FileInfo[] fis = d.GetFiles();
            foreach (FileInfo fi in fis)
            {
                size += fi.Length;
            }
            // Add subdirectory sizes.
            DirectoryInfo[] dis = d.GetDirectories();
            foreach (DirectoryInfo di in dis)
            {
                size += DirSize(di);
            }
            return size;
        }
    }
}

这适用于某些文件夹,但是在尝试在顶级文件夹上运行它时会引发错误。

托管调试助手“ContextSwitchDeadlock”消息=托管调试助手“ContextSwitchDeadlock”:“CLR 在 60 秒内无法从 COM 上下文 0x134c510 转换到 COM 上下文 0x134c458。拥有目标上下文/单元的线程很可能要么进行非泵送等待,要么处理非常长时间运行的操作而不泵送 Windows 消息。这种情况通常会对性能产生负面影响,甚至可能导致应用程序变得无响应或内存使用量随着时间的推移不断累积。为避免此问题,所有单线程单元 (STA) 线程都应使用泵送等待原语(例如 CoWaitForMultipleHandles)并在长时间运行的操作期间定期泵送消息。

我试图添加但没有成功:

try
{
}
catch()
{
}

有什么方法可以改善它:

此外,如果我分别为每个子文件夹执行此操作(例如管理、项目、数据库等),一切正常。但是,在顶级文件夹(公司)上运行当前代码会引发错误。

标签: c#wpf

解决方案


添加 acatch{}不会修复任何错误,它只会隐藏它们。他们还在那里。在这种情况下,应用程序会抱怨,因为代码冻结了 UI 超过 60 秒。在已经冻结的 UI 线程中使用catch{}不会解决问题

对于初学者,使用Directory.EnumerateFiles(string searchPattern, System.IO.SearchOption searchOption)AllDirectories选项列出所有文件,而不仅仅是顶级目录。在后台运行它,这样 UI 就不会冻结,例如:

private async void Button_Click(object sender, RoutedEventArgs e)
{
    string targetFolder = PathSrc.Text;
    var dir=new DirectoryInfo(targetFolder);

    var size=await Task.Run(()=> 
            dir.EnumerateFiles("*",SearchOption.AllDirectories)
               .Sum(fi=>fi.Length));

    MessageBox.Show ("The size is " + size / 1000000 + " MB.");
}

推荐阅读