here it is the FULL source code : http://pastebin.com/mLaGwwi0 As you will notice , the thing is to scan directories and files and populate them in a tree view. I am using background worker (the same happens with Threads class) to do that in background, while updating treeview with nodes one by one. The thing is that it is not working in background and not updating the treeview. This is the part of code which is hanging the form :
public void ListDirectory(DirectoryInfo path)
{
treeView1.Nodes.Add(CreateDirectoryNode(path));
}
public void Addnode(DirectoryInfo dirinfo)
{
Invoke(new AddCDAnode(ListDirectory), new object[] { dirinfo });
}
private TreeNode CreateDirectoryNode(DirectoryInfo directoryInfo)
{
var directoryNode = new TreeNode(directoryInfo.Name);
foreach (var directory in directoryInfo.GetDirectories())
{
//Statustext = directory.FullName;
directoryNode.Nodes.Add(CreateDirectoryNode(directory));
}
foreach (var file in directoryInfo.GetFiles())
directoryNode.Nodes.Add(new TreeNode(file.Name));
return directoryNode;
}
public delegate void AddCDAnode(DirectoryInfo dirinfo);
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
DirectoryInfo dir = new DirectoryInfo(@"\\server\trabajos 2013\");
Addnode(dir);
}
private void Form1_Load(object sender, EventArgs e)
{
//Start filling the TreeView on a separate thread
backgroundWorker1.RunWorkerAsync();
}
In full source code you will see commented code - that is from example and working in background without any troubles. So i think the problem is with my code of scanning directories.
The solution is also available here, if you want to download it.
The problem is that you start a background thread, but then immediately go and call
Invoke
to run basically all of your real code in the UI thread, consequently the UI thread is being blocked.What you need to do is separate out your UI logic from your non-UI logic. Ensure that the non-UI logic is executed in the background thread, and that the UI logic is executed in the UI thread.
In this case,
CreateDirectoryNode(path)
is basically all of your non-UI work. It's doing a whole bunch of file manipulation (which is time consuming) and in general creating the data that your UI will later use.That should be done in the
DoWork
event of your background worker. Then you can set theResult
property of the BGW based on the results it generated so that it can be used later.For the UI portion, which is the
treeView1.Nodes.Add(
call, that should be in theRunWorkerCompleted
event. That event is designed for you to manipulate the UI based on the results of the long running task. There you can read in theResult
property of the BGW (it is a property in the arguments passed to the event handler) and there it can add the data to the tree view. Since this is in the UI thread you won't get cross thread exceptions, and since your long running file IO is done in the background thread it won't hand the UI.So all you need is your
CreateDirectryNode
method and the following: