C#.Net在迭代大量文件时冻结

时间:2016-06-28 18:27:56

标签: c# iteration freeze filesystem-access

我遇到一个问题,我编写了一个应用程序,它会遍历文件并为每个文件的整数添加+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);
    }
}

顺便说一句。抱歉我的英文不好

此致

2 个答案:

答案 0 :(得分:10)

因为您正在UI线程上完成所有工作,所以它在工作时无法刷新。您需要在后台线程上完成工作,然后以线程安全的方式更新UI。同样切换到Directory.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;
        }
    }
}

(代码是从内存中在Web浏览器中编写的,因此可能存在错误)

答案 1 :(得分:-1)

好像你正在使用一个非常耗时的循环而没有处理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);
    }
}