How to access Directory.EnumerateFiles directory before it finishes

In the question that I asked, Get a list of file names in a folder and all subfolders quickly. And a few others that I found seem to search for many files to use the EnumerateFiles method.

The EnumerateFiles and GetFiles methods differ as follows: When you use EnumerateFiles, you can start enumerating a collection of names before returning the entire collection; when you use GetFiles, you must wait for the entire array of names to be returned before you can access the array. Therefore, when you work with many files and directories, EnumerateFiles can be more efficient.

That sounds great to me, my search takes about 10 seconds, so I can start customizing my list as the information comes in. But I can’t figure it out. When I run the EnumerateFiles method, the application freezes until it finishes. I could run it in the background desktop, but the same thing would happen with this thread. Any help?

 DirectoryInfo dir = new DirectoryInfo(MainFolder);
 List<FileInfo> matches = new List<FileInfo>(dir.EnumerateFiles("*.docx",SearchOption.AllDirectories));

//This wont fire until after the entire collection is complete
DoSoemthingWhileWaiting();
+3
source share
3 answers

You can do this by clicking it in the background task.

For example, you can do:

var fileTask = Task.Factory.StartNew( () =>
{
    DirectoryInfo dir = new DirectoryInfo(MainFolder);
    return new List<FileInfo>(
           dir.EnumerateFiles("*.docx",SearchOption.AllDirectories)
           .Take(200) // In previous question, you mentioned only wanting 200 items
       );
};

// To process items:
fileTask.ContinueWith( t =>
{
     List<FileInfo> files = t.Result;

     // Use the results...
     foreach(var file in files)
     {
         this.listBox.Add(file); // Whatever you want here...
     }
}, TaskScheduler.FromCurrentSynchronizationContext()); // Make sure this runs on the UI thread

DoSomethingWhileWaiting();

You mentioned in a comment:

I want to display them in a list. and perfect send them to the main ui when they come in

In this case, you will have to process them in the background and add them to the list as they become available. Sort of:

Task.Factory.StartNew( () =>
{
    DirectoryInfo dir = new DirectoryInfo(MainFolder);
    foreach(var tmp in dir.EnumerateFiles("*.docx",SearchOption.AllDirectories).Take(200))
    {
        string file = tmp; // Handle closure issue

        // You may want to do this in batches of >1 item...
        this.BeginInvoke( new Action(() =>
        {
             this.listBox.Add(file);
        }));
    }
});
DoSomethingWhileWaiting();
+11
source

, , List<FileInfo>. . , - , , , .

, .

, , , , , : . , , , , . WinForms Control.Invoke. , , , , . , .

:

Task.Factory.StartNew(() =>
{
    var dir = new DirectoryInfo(MainFolder);
    var files = dir.EnumerateFiles("*.docx", SearchOption.AllDirectories);
    foreach (var file in files)
    {
        Action<string> del = f => listBox1.Items.Add((string)f);
        BeginInvoke(del, file);
    }
});
+7

    forach(var f in dir.EnumerateFiles("*.docx",SearchOption.AllDirectories))
    {
//.. process file
    }

+4

All Articles