1

我正在尝试在下面的函数中穿线,以便背景表单可以继续移动并且不会“冻结”,有人可以帮我这样做吗?

    public IEnumerable<string> GetFiles(string path) 
    {
        Queue<string> queue = new Queue<string>();
        queue.Enqueue(path);
        while (queue.Count > 0)
        {
            path = queue.Dequeue();
            try
            {
                foreach (string subDir in Directory.GetDirectories(path))
                {
                    queue.Enqueue(subDir);
                }
            }
            catch (Exception ex)
            {
                richTextBox1.AppendText(ex.Message);
            }
            string[] files = null;
            try
            {
                files = Directory.GetFiles(path);
            }
            catch (Exception ex)
            {
                richTextBox1.AppendText(ex.Message);
            }
            if (files != null)
            {
                for (int i = 0; i < files.Length; i++)
                {
                    yield return files[i];
                }
            }
        }
    }

我使用以下按钮执行代码:

 private void button1_Click(object sender, EventArgs e)
    {
        int count = 0;
        FolderBrowserDialog dialog = new FolderBrowserDialog();
        dialog.ShowDialog();
        string selected = dialog.SelectedPath;

        foreach (string file in GetFiles(selected))
        {
            count++;
            richTextBox1.AppendText(file + Environment.NewLine);

        }
        label2.Text = count.ToString();
    }
4

1 回答 1

4

将整个事情放入后台线程(可能与.NET 4 中可能与),并在您想要更新 UI 时使用BackgroundWorker或封送回 UI 线程。TaskControl.InvokeControl.BeginInvoke

您将无法仅GetFiles在 UI 中调用和使用结果 - 至少在 C# 5 之前,这将通过 async/await 使这一切变得更容易 - 但您可以让后台线程“告诉” UI 线程何时它已完成 - 以及当它找到每个单独的文件时。基本上,放弃迭代器块,要么count在类中保持状态,要么让后台线程在完成后回调 UI 线程时报告总计数。

于 2011-11-01T17:49:04.857 回答