Sign in to follow this  

[.net] How to use threads to iterate through file system?

This topic is 4301 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Since I am quite unexperienced in Thread programming, I would like to hear some tips or other solutions to a problem of mine. I am writing a folder tree size analyzer. The user can choose which folders that the app should analyze. Since iterating through a file system can take quite some time, I want to let threads do the work. My (incomplete) solution: I have a class AnalysisEngine which contains methods and fields for the task. When a user wants to have a folder analyzed, the MainForm adds that folder to a list in AnalysisEngine. A thread regularly checks the list (a static field) for items. When the list contains an item, the thread begins to iterate the file system to build up a complete folder tree. When that is done, it adds the (root of the) tree to another list. The second list is also regularly checked by another thread. When it finds a tree, it iterates through the list and calculate the size of each folder. When that is done, it adds the tree to a third list where finnished trees are. The program can the query the AnalysisEngine for data from the third list, and then render the results in a TreeView for instance. The problem is that the user might change his/her mind and at anytime remove a folder from the list of folders to analyze. If a thread is not iterating through the filesystem, it is a piece of cake: check all lists and remove any occurances of that folder. However, if a thread is iterating through a folder, how can the thread 'be told' to stop iterating that folder tree and look for other folders to analyze? Since Thread.Abort() makes the thread unusuble afterwards, that is not a good method. Besides, it is not even recomended. The method that one of the threads runs would go something like
// This method is constantly run by a thread.
public void RegularlyCheckFolderQueue()
{
    while (applicationIsRunning) {
        // Check for folders to analyze 10 times each second.
        Thread.Sleep(100);
        if (AnalysisEngine.ListOfFolderToBuildTreeFrom.Count > 0) {
            AnalysisEngine.ListOfFolderToBuildTreeFrom.RemoveFirst();
            AnalysisEngine.ListOfFoldersToAnalyze.AddFirst(AnalysisEngine.BuildFolderTree(AnalysisEngine.ListOfFoldersToBuildTreeFrom.First));
        }
    }
}






Am I looking at the problem from the wrong viewpoint? Can it be solved more elegantly (like without static fields)? Any tips appreciated! [Edited by - Enselic on March 1, 2006 3:37:46 PM]

Share this post


Link to post
Share on other sites
One way might be to force the threads to check a boolean array (one element per thread) which, when TRUE, keeps the thread going. A user cancelling would set the appropriate value to FALSE getting the thread to complete its task when it next checks the array.

I'm not sure getting the threads to check a sync block like this is good practise, but it works for me. (Remember to mark the array with the volatile modifier so that changes get written immediately back to it).

Phillip Hamlyn

Share this post


Link to post
Share on other sites
Thanks for the reply!

The difficulty lies in the fact that once the thread starts to handle data, it does that by recursivly calling methods.

The method that gets called recursivly goes like this

/// <summary>
/// Gets the childs to the Childs property of the folder. This method is also called on
/// each child.
/// </summary>
public void RetriveChilds()
{
string[] subDirPaths;

try {
subDirPaths = Directory.GetDirectories(FullPath);
} catch (SystemException) {
readAcces = false;
return;
}

foreach (string subDirPath in subDirPaths) {
FileSystemFolder subDir = new FileSystemFolder(subDirPath, this);

subDir.RetriveChilds();

Childs.Add(subDir);
}

NbrOfFileSystemFolders += subDirPaths.Length;
}




which is a method on the class FileSystemFolder.

What the thread would do when it finds items in the list is to create a root-FileSystemFolder, and then call RetriveChilds() on that node. That will recursivly build the folder tree.

This makes it hard to let the thread look up if it should continue iterating since it 'gets lost' within a lots of RetriveChilds()-calls.

I suspect that I am on the wrong track, i.e. there might be another way of doing the whole thing.

Keep 'em comments coming! .

Share this post


Link to post
Share on other sites
How big a problem is this?

Maybe I'm just looking at it oddly, but the scenario where a user will change their mind seems slim. Why not just let the thread run through to completion, and toss the results if it's for a file that the user excluded? Seems like less of an impact than making every thread waste time checking to see if the user changed their minds.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Just one idea...

For each thread that is working on a folder I would just create a variable that contains the folder that it is working on.

If the user removes a folder check if it effects one of your threads by just comparing with that variables. If it has, set a boolean that belongs to that thread to true. But don't set it to false under any conditions from here.

You then have to check in each iteration if the boolean is true, and return if it is. When you proceed to the next folder in your list always reset it to false.

Share this post


Link to post
Share on other sites
By coincidence I stumbled across an MSDN article named How to: Create and Terminate Threads which gave some insight in what a solution could look like. The key here is the volatile keyword.

I also found another article worth a read for multithreaders, named How To Stop a Thread in .NET (and Why Thread.Abort is Evil).

Telastyn
You have good point, chances that someone would change their mind are slim. However, I would like to give users a feel of a high quality application, and a HQ app would allow the user to stop a background pocess whenever he/she feels for it.

AP
I will use such a solution with the volatile keyword added.

Share this post


Link to post
Share on other sites

This topic is 4301 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this