Reputation: 339
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();
}
Upvotes: 1
Views: 1053
Reputation: 1502076
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.
Upvotes: 4