c# How do you thread a recursive directory search?

1k views Asked by At

I'm trying to thread this below function so that the background form can continue to be moved around and won't 'freeze', can anyone assist me in doing this?

    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];
                }
            }
        }
    }

I execute the code with the following button:

 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();
    }
1

There are 1 answers

3
Jon Skeet On BEST ANSWER

Put the whole thing into a background thread (possibly with BackgroundWorker, possibly with Task in .NET 4) and use Control.Invoke or Control.BeginInvoke to marshal back to the UI thread when you want to update the UI.

You won't be able to just call GetFiles and use the result in the UI - at least until C# 5, which will make all this a lot easier with async/await - but you can make the background thread "tell" the UI thread when it's completed - and also when it's found each individual file. Basically, abandon the iterator block, and either keep count as state within the class, or get the background thread to report the total count when it calls back to the UI thread when it's finished.