C#.Net在遍历大量文件时冻结

C#.Net在遍历大量文件时冻结,c#,iteration,freeze,filesystem-access,C#,Iteration,Freeze,Filesystem Access,我有一个问题,我编写了一个应用程序,该应用程序将遍历文件,并将每个文件的整数加上+1,直到它到达一个特定的文件名。问题可能是因为.Net不直接访问本机文件系统,它会填充集合,但就我而言,这需要几年时间,相信我,目标文件夹中有26万个文件。迭代甚至没有到达第二个文件。线程完全冻结,没有错误,没有异常。那么,有没有任何方法可以直接访问本机文件系统而不必填充无用的集合 这是我的密码: private void button1_Click(object sender, EventArgs e) {

我有一个问题,我编写了一个应用程序,该应用程序将遍历文件,并将每个文件的整数加上+1,直到它到达一个特定的文件名。问题可能是因为.Net不直接访问本机文件系统,它会填充集合,但就我而言,这需要几年时间,相信我,目标文件夹中有26万个文件。迭代甚至没有到达第二个文件。线程完全冻结,没有错误,没有异常。那么,有没有任何方法可以直接访问本机文件系统而不必填充无用的集合

这是我的密码:

private void button1_Click(object sender, EventArgs e)
{
    try
    {
        foreach (string file in Directory.GetFiles("\\\\Mypcname-PC\\vxheaven\\malware"))
        {
            count++;
            label1.Text = Convert.ToString(count);
            if (file.Contains(textBox1.Text))
            {
                label1.Text = Convert.ToString(count) + " reached the file";
                break;
            }
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}
顺便说一句,很抱歉我的英语不好


关于

,因为您正在执行UI线程上的所有工作,因此它在工作时无法刷新。您需要在后台线程上完成工作,然后以线程安全的方式更新UI。同时切换到
目录.EnumerateFiles
将加快读取第一个文件的速度,因此它不需要将所有记录存储到数组中。最后,我将
ex.Message
更改为
ex.ToString()
,这样会显示更多有用的信息

private async void button1_Click(object sender, EventArgs e)
{
    try
    {
         var text = textBox1.Text;
         var progress = new Progress<string>((x) => label1.Text = x);
         await Task.Run(() => DoWork(progress, text));
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }
}

private void DoWork(IProgress<string> progress, string text)
{
    foreach (string file in Directory.EnumerateFiles("\\\\Mypcname-PC\\vxheaven\\malware"))
    {
        count++;
        progress.Report(Convert.ToString(count));
        if (file.Contains(text))
        {
            progress.Report(Convert.ToString(count) + " reached the file");
            break;
        }
    }
}
private async void按钮1\u单击(对象发送方,事件参数e)
{
尝试
{
var text=textBox1.text;
变量进度=新进度((x)=>label1.Text=x);
等待任务。运行(()=>DoWork(进度,文本));
}
捕获(例外情况除外)
{
Show(例如ToString());
}
}
私有void DoWork(IProgress progress,字符串文本)
{
foreach(目录中的字符串文件。枚举文件(\\\\Mypcname PC\\vxheaven\\malware”))
{
计数++;
进度报告(转换为字符串(计数));
if(file.Contains(text))
{
progress.Report(Convert.ToString(count)+“已到达文件”);
打破
}
}
}

(代码是从内存写入web浏览器的,因此可能会有错误)

似乎您正在使用一个可能非常耗时的循环,而从未处理Windows消息队列,因此您的应用程序可能会被冻结,而它可能正忙着执行您在循环中指示它执行的操作。试试这个:

private void button1_Click(object sender, EventArgs e)
{
    try
    {
        foreach (string file in Directory.GetFiles("\\\\Mypcname-PC\\vxheaven\\malware"))
        {
            count++;
            label1.Text = Convert.ToString(count);
            Application.DoEvents();
            if (file.Contains(textBox1.Text))
            {
                label1.Text = Convert.ToString(count) + " reached the file";
                break;
            }
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

如果您希望我们帮助您使用代码,您需要显示您的代码。并包含对文件进行评分的代码。如果代码中从未包含第二个元素,那么这听起来像是个问题。可能是因为听起来您可能正在修改集合或者我忘记包含我使用的目录.GetFiles()信息不足,我们需要查看,否则您的问题将被关闭。您的UI线程在这里被锁定。您应该在线程安全的BackgroundWorker/Task上执行操作,并根据worker/Task返回的进度更新UI。考虑到这一点,但我认为这不是问题所在,我将对此进行检查。它看起来不起作用的原因是因为您阻止了UI,它正在工作,但它无法告诉您它正在工作。Kay,复制到project中,唯一的问题是,我应该包括哪些其他参考?使用System.Threading.Tasks添加
到文件的顶部。此外,此代码需要.NET4.5或更高版本非常危险,如果不小心,可能会破坏程序的内部状态。你不应该把它作为你的第一选择。这是一个快速而肮脏的修复,没有改变他的原始代码。当然,您的代码要好得多(投票支持您的答案),但这是一次完全的重写,而不是修复