Threading and Treeviews

C

Chris

Hi everyone-

So I have this treeview control that I'm populating from a dataset.
Problem is, there are 10 tables in the dataset (I didn't set the
database up, for the record). So I'm having to make 10 foreach loops
to get all the 'branches' in the treeview. As you might expect, this
is super slow. So I was thinking I could thread it. Build the first
half of the treeview in one thread, build the second half in the other
thread, and put the two together. Now in the processes that my thread
executes, I'm adding my treenodes. And when I add breakpoints and
check, they're allegedly there. But when the page renders, there's no
treeview displayed.


public void TestThread()
{
TreeView tvTemp = new TreeView();
Thread[] thTempThread = new Thread[2];
thTempThread[0] = new Thread(new ThreadStart(BuildListPart1));
thTempThread[1] = new Thread(new ThreadStart(BuildListPart2));
thTempThread[0].Start();
thTempThread[1].Start();
}

public void BuildListPart1()
{
foreach (DataRow drChapter in
Books.dsBookTOC().Tables[2].Rows) //Get all book chapters
{
foreach (DataRow drChapNum in
drChapter.GetChildRows("ChapterTable")) //Get all chapter numbers
pertaining to this book
{
TreeNode trChapter = new
TreeNode(drChapter[5].ToString(), drChapter[3].ToString());
tvChapterList.Nodes.Add(trChapter);
foreach (DataRow drSection in
drChapNum.GetChildRows("Section")) //Get all Sections pertaining to
this chapter
{
TreeNode trSection = new
TreeNode(drSection[3].ToString() + " " + drSection[4].ToString(),
drSection[1].ToString());
trChapter.ChildNodes.Add(trSection);
}
}
}
}

And the second function grabs the rest of the list. Do I have to pass
my treeview as a parameterized thread, or something? Any help is
appreciated.
 
C

Ciaran O''Donnell

You cant call TreeVire.Nodes.Add from a thread, only from the UI thread (the
main thread normally). You need to write a function to do it an invoke it via
the control:


public void TestThread()
{
TreeView tvTemp = new TreeView();
Thread[] thTempThread = new Thread[2];
thTempThread[0] = new Thread(new ThreadStart(BuildListPart1));
thTempThread[1] = new Thread(new ThreadStart(BuildListPart2));
thTempThread[0].Start();
thTempThread[1].Start();
}

TreeView tvChapterList;

public void BuildListPart1()
{
foreach (DataRow drChapter in Books.dsBookTOC().Tables[2].Rows) //Get all
book chapters
{
foreach (DataRow drChapNum in drChapter.GetChildRows("ChapterTable")) //Get
all chapter numbers pertaining to this book
{
TreeNode trChapter = new TreeNode(drChapter[5].ToString(),
drChapter[3].ToString());
foreach (DataRow drSection in drChapNum.GetChildRows("Section")) //Get all
Sections pertaining to this chapter
{
TreeNode trSection = new TreeNode(drSection[3].ToString() + " " +
drSection[4].ToString(), drSection[1].ToString());
trChapter.ChildNodes.Add(trSection);
}
tvChapterList.Invoke(AddChapterTreeViewNode, trChapter);


}
}
}

private void AddChapterTreeViewNode(TreeNode node)
{
tvChapterList.Nodes.Add(node);
}

--
Ciaran O''Donnell
http://wannabedeveloper.spaces.live.com


Chris said:
Hi everyone-

So I have this treeview control that I'm populating from a dataset.
Problem is, there are 10 tables in the dataset (I didn't set the
database up, for the record). So I'm having to make 10 foreach loops
to get all the 'branches' in the treeview. As you might expect, this
is super slow. So I was thinking I could thread it. Build the first
half of the treeview in one thread, build the second half in the other
thread, and put the two together. Now in the processes that my thread
executes, I'm adding my treenodes. And when I add breakpoints and
check, they're allegedly there. But when the page renders, there's no
treeview displayed.


public void TestThread()
{
TreeView tvTemp = new TreeView();
Thread[] thTempThread = new Thread[2];
thTempThread[0] = new Thread(new ThreadStart(BuildListPart1));
thTempThread[1] = new Thread(new ThreadStart(BuildListPart2));
thTempThread[0].Start();
thTempThread[1].Start();
}

public void BuildListPart1()
{
foreach (DataRow drChapter in
Books.dsBookTOC().Tables[2].Rows) //Get all book chapters
{
foreach (DataRow drChapNum in
drChapter.GetChildRows("ChapterTable")) //Get all chapter numbers
pertaining to this book
{
TreeNode trChapter = new
TreeNode(drChapter[5].ToString(), drChapter[3].ToString());
tvChapterList.Nodes.Add(trChapter);
foreach (DataRow drSection in
drChapNum.GetChildRows("Section")) //Get all Sections pertaining to
this chapter
{
TreeNode trSection = new
TreeNode(drSection[3].ToString() + " " + drSection[4].ToString(),
drSection[1].ToString());
trChapter.ChildNodes.Add(trSection);
}
}
}
}

And the second function grabs the rest of the list. Do I have to pass
my treeview as a parameterized thread, or something? Any help is
appreciated.
 
C

Chris

So I develop the node structure first, then use Invoke to attach the
root node to the treeview? Interesting. Thanks for the tip!

You cant call TreeVire.Nodes.Add from a thread, only from the UI thread (the
main thread normally). You need to write a function to do it an invoke itvia
the control:

public void TestThread()
{
TreeView tvTemp = new TreeView();
Thread[] thTempThread = new Thread[2];
thTempThread[0] = new Thread(new ThreadStart(BuildListPart1));
thTempThread[1] = new Thread(new ThreadStart(BuildListPart2));
thTempThread[0].Start();
thTempThread[1].Start();

}

TreeView tvChapterList;

public void BuildListPart1()
{
foreach (DataRow drChapter in Books.dsBookTOC().Tables[2].Rows)  //Get all
book chapters
{
foreach (DataRow drChapNum in drChapter.GetChildRows("ChapterTable"))  //Get
all chapter numbers pertaining to this book
{
TreeNode trChapter = new TreeNode(drChapter[5].ToString(),
drChapter[3].ToString());
foreach (DataRow drSection in drChapNum.GetChildRows("Section")) //Get all
Sections pertaining to this chapter
{
        TreeNode trSection = new TreeNode(drSection[3].ToString() + " " +
drSection[4].ToString(), drSection[1].ToString());
        trChapter.ChildNodes.Add(trSection);}

tvChapterList.Invoke(AddChapterTreeViewNode, trChapter);

}
}
}

private void AddChapterTreeViewNode(TreeNode node)
{
tvChapterList.Nodes.Add(node);

}

--
Ciaran O''Donnellhttp://wannabedeveloper.spaces.live.com



Chris said:
Hi everyone-
So I have this treeview control that I'm populating from a dataset.
Problem is, there are 10 tables in the dataset (I didn't set the
database up, for the record).  So I'm having to make 10 foreach loops
to get all the 'branches' in the treeview.  As you might expect, this
is super slow.  So I was thinking I could thread it.  Build the first
half of the treeview in one thread, build the second half in the other
thread, and put the two together.  Now in the processes that my thread
executes, I'm adding my treenodes.  And when I add breakpoints and
check, they're allegedly there.  But when the page renders, there's no
treeview displayed.
 public void TestThread()
    {
        TreeView tvTemp = new TreeView();
        Thread[] thTempThread = new Thread[2];
        thTempThread[0] = new Thread(new ThreadStart(BuildListPart1));
        thTempThread[1] = new Thread(new ThreadStart(BuildListPart2));
        thTempThread[0].Start();
        thTempThread[1].Start();
    }
    public void BuildListPart1()
    {
        foreach (DataRow drChapter in
Books.dsBookTOC().Tables[2].Rows)  //Get all book chapters
        {
            foreach (DataRow drChapNum in
drChapter.GetChildRows("ChapterTable"))  //Get all chapter numbers
pertaining to this book
            {
                TreeNode trChapter = new
TreeNode(drChapter[5].ToString(), drChapter[3].ToString());
                tvChapterList.Nodes.Add(trChapter);
                foreach (DataRow drSection in
drChapNum.GetChildRows("Section")) //Get all Sections pertaining to
this chapter
                {
                    TreeNode trSection = new
TreeNode(drSection[3].ToString() + " " + drSection[4].ToString(),
drSection[1].ToString());
                    trChapter.ChildNodes.Add(trSection);
                }
            }
        }
    }
And the second function grabs the rest of the list.  Do I have to pass
my treeview as a parameterized thread, or something?  Any help is
appreciated.
 
C

Chris

Well I wasn't able to use Invoke (intellisense didn't recognize it),
so I did a straight call to the addchaptertreeviewnode function, and
that didn't work either. Any ideas?

You cant call TreeVire.Nodes.Add from a thread, only from the UI thread (the
main thread normally). You need to write a function to do it an invoke itvia
the control:

public void TestThread()
{
TreeView tvTemp = new TreeView();
Thread[] thTempThread = new Thread[2];
thTempThread[0] = new Thread(new ThreadStart(BuildListPart1));
thTempThread[1] = new Thread(new ThreadStart(BuildListPart2));
thTempThread[0].Start();
thTempThread[1].Start();

}

TreeView tvChapterList;

public void BuildListPart1()
{
foreach (DataRow drChapter in Books.dsBookTOC().Tables[2].Rows)  //Get all
book chapters
{
foreach (DataRow drChapNum in drChapter.GetChildRows("ChapterTable"))  //Get
all chapter numbers pertaining to this book
{
TreeNode trChapter = new TreeNode(drChapter[5].ToString(),
drChapter[3].ToString());
foreach (DataRow drSection in drChapNum.GetChildRows("Section")) //Get all
Sections pertaining to this chapter
{
        TreeNode trSection = new TreeNode(drSection[3].ToString() + " " +
drSection[4].ToString(), drSection[1].ToString());
        trChapter.ChildNodes.Add(trSection);}

tvChapterList.Invoke(AddChapterTreeViewNode, trChapter);

}
}
}

private void AddChapterTreeViewNode(TreeNode node)
{
tvChapterList.Nodes.Add(node);

}

--
Ciaran O''Donnellhttp://wannabedeveloper.spaces.live.com



Chris said:
Hi everyone-
So I have this treeview control that I'm populating from a dataset.
Problem is, there are 10 tables in the dataset (I didn't set the
database up, for the record).  So I'm having to make 10 foreach loops
to get all the 'branches' in the treeview.  As you might expect, this
is super slow.  So I was thinking I could thread it.  Build the first
half of the treeview in one thread, build the second half in the other
thread, and put the two together.  Now in the processes that my thread
executes, I'm adding my treenodes.  And when I add breakpoints and
check, they're allegedly there.  But when the page renders, there's no
treeview displayed.
 public void TestThread()
    {
        TreeView tvTemp = new TreeView();
        Thread[] thTempThread = new Thread[2];
        thTempThread[0] = new Thread(new ThreadStart(BuildListPart1));
        thTempThread[1] = new Thread(new ThreadStart(BuildListPart2));
        thTempThread[0].Start();
        thTempThread[1].Start();
    }
    public void BuildListPart1()
    {
        foreach (DataRow drChapter in
Books.dsBookTOC().Tables[2].Rows)  //Get all book chapters
        {
            foreach (DataRow drChapNum in
drChapter.GetChildRows("ChapterTable"))  //Get all chapter numbers
pertaining to this book
            {
                TreeNode trChapter = new
TreeNode(drChapter[5].ToString(), drChapter[3].ToString());
                tvChapterList.Nodes.Add(trChapter);
                foreach (DataRow drSection in
drChapNum.GetChildRows("Section")) //Get all Sections pertaining to
this chapter
                {
                    TreeNode trSection = new
TreeNode(drSection[3].ToString() + " " + drSection[4].ToString(),
drSection[1].ToString());
                    trChapter.ChildNodes.Add(trSection);
                }
            }
        }
    }
And the second function grabs the rest of the list.  Do I have to pass
my treeview as a parameterized thread, or something?  Any help is
appreciated.
 
C

Ciaran O''Donnell

I assumed you were building a windows forms application.
The problem is that you request finishes before the threads have finished
processing and adding the child nodes. What you need to do it wait till all
the threads are finished so you KNOW the treeview has its nodes before you
return.

Try this:

public void TestThread()
{
TreeView tvTemp = new TreeView();
Thread[] thTempThread = new Thread[2];
thTempThread0 = new Thread(new ThreadStart(BuildListPart1));
thTempThread1 = new Thread(new ThreadStart(BuildListPart2));
thTempThread[0].Start();
thTempThread[1].Start();

foreach(Thread t in thTempThread) t.Join();
}


--
Ciaran O''Donnell
http://wannabedeveloper.spaces.live.com


Chris said:
Well I wasn't able to use Invoke (intellisense didn't recognize it),
so I did a straight call to the addchaptertreeviewnode function, and
that didn't work either. Any ideas?

You cant call TreeVire.Nodes.Add from a thread, only from the UI thread (the
main thread normally). You need to write a function to do it an invoke it via
the control:

public void TestThread()
{
TreeView tvTemp = new TreeView();
Thread[] thTempThread = new Thread[2];
thTempThread[0] = new Thread(new ThreadStart(BuildListPart1));
thTempThread[1] = new Thread(new ThreadStart(BuildListPart2));
thTempThread[0].Start();
thTempThread[1].Start();

}

TreeView tvChapterList;

public void BuildListPart1()
{
foreach (DataRow drChapter in Books.dsBookTOC().Tables[2].Rows) //Get all
book chapters
{
foreach (DataRow drChapNum in drChapter.GetChildRows("ChapterTable")) //Get
all chapter numbers pertaining to this book
{
TreeNode trChapter = new TreeNode(drChapter[5].ToString(),
drChapter[3].ToString());
foreach (DataRow drSection in drChapNum.GetChildRows("Section")) //Get all
Sections pertaining to this chapter
{
TreeNode trSection = new TreeNode(drSection[3].ToString() + " " +
drSection[4].ToString(), drSection[1].ToString());
trChapter.ChildNodes.Add(trSection);}

tvChapterList.Invoke(AddChapterTreeViewNode, trChapter);

}
}
}

private void AddChapterTreeViewNode(TreeNode node)
{
tvChapterList.Nodes.Add(node);

}

--
Ciaran O''Donnellhttp://wannabedeveloper.spaces.live.com



Chris said:
Hi everyone-
So I have this treeview control that I'm populating from a dataset.
Problem is, there are 10 tables in the dataset (I didn't set the
database up, for the record). So I'm having to make 10 foreach loops
to get all the 'branches' in the treeview. As you might expect, this
is super slow. So I was thinking I could thread it. Build the first
half of the treeview in one thread, build the second half in the other
thread, and put the two together. Now in the processes that my thread
executes, I'm adding my treenodes. And when I add breakpoints and
check, they're allegedly there. But when the page renders, there's no
treeview displayed.
public void TestThread()
{
TreeView tvTemp = new TreeView();
Thread[] thTempThread = new Thread[2];
thTempThread[0] = new Thread(new ThreadStart(BuildListPart1));
thTempThread[1] = new Thread(new ThreadStart(BuildListPart2));
thTempThread[0].Start();
thTempThread[1].Start();
}
public void BuildListPart1()
{
foreach (DataRow drChapter in
Books.dsBookTOC().Tables[2].Rows) //Get all book chapters
{
foreach (DataRow drChapNum in
drChapter.GetChildRows("ChapterTable")) //Get all chapter numbers
pertaining to this book
{
TreeNode trChapter = new
TreeNode(drChapter[5].ToString(), drChapter[3].ToString());
tvChapterList.Nodes.Add(trChapter);
foreach (DataRow drSection in
drChapNum.GetChildRows("Section")) //Get all Sections pertaining to
this chapter
{
TreeNode trSection = new
TreeNode(drSection[3].ToString() + " " + drSection[4].ToString(),
drSection[1].ToString());
trChapter.ChildNodes.Add(trSection);
}
}
}
}
And the second function grabs the rest of the list. Do I have to pass
my treeview as a parameterized thread, or something? Any help is
appreciated.
 
C

Chris

Perfect! Just what I needed! Thanks a bunch!

I assumed you were building a windows forms application.
The problem is that you request finishes before the threads have finished
processing and adding the child nodes. What you need to do it wait till all
the threads are finished so you KNOW the treeview has its nodes before you
return.

Try this:

public void TestThread()
{
        TreeView tvTemp = new TreeView();
        Thread[] thTempThread = new Thread[2];
        thTempThread0 = new Thread(new ThreadStart(BuildListPart1));
        thTempThread1 = new Thread(new ThreadStart(BuildListPart2));
        thTempThread[0].Start();
        thTempThread[1].Start();

        foreach(Thread t in thTempThread) t.Join();

}

--
Ciaran O''Donnellhttp://wannabedeveloper.spaces.live.com



Chris said:
Well I wasn't able to use Invoke (intellisense didn't recognize it),
so I did a straight call to the addchaptertreeviewnode function, and
that didn't work either.  Any ideas?
You cant call TreeVire.Nodes.Add from a thread, only from the UI thread (the
main thread normally). You need to write a function to do it an invoke it via
the control:
public void TestThread()
{
TreeView tvTemp = new TreeView();
Thread[] thTempThread = new Thread[2];
thTempThread[0] = new Thread(new ThreadStart(BuildListPart1));
thTempThread[1] = new Thread(new ThreadStart(BuildListPart2));
thTempThread[0].Start();
thTempThread[1].Start();
}
TreeView tvChapterList;
public void BuildListPart1()
{
foreach (DataRow drChapter in Books.dsBookTOC().Tables[2].Rows)  //Get all
book chapters
{
foreach (DataRow drChapNum in drChapter.GetChildRows("ChapterTable")) //Get
all chapter numbers pertaining to this book
{
TreeNode trChapter = new TreeNode(drChapter[5].ToString(),
drChapter[3].ToString());
foreach (DataRow drSection in drChapNum.GetChildRows("Section")) //Get all
Sections pertaining to this chapter
{
        TreeNode trSection = new TreeNode(drSection[3].ToString() + " " +
drSection[4].ToString(), drSection[1].ToString());
        trChapter.ChildNodes.Add(trSection);}
tvChapterList.Invoke(AddChapterTreeViewNode, trChapter);
}
}
}
private void AddChapterTreeViewNode(TreeNode node)
{
tvChapterList.Nodes.Add(node);
}
--
Ciaran O''Donnellhttp://wannabedeveloper.spaces.live.com
:
Hi everyone-
So I have this treeview control that I'm populating from a dataset.
Problem is, there are 10 tables in the dataset (I didn't set the
database up, for the record).  So I'm having to make 10 foreach loops
to get all the 'branches' in the treeview.  As you might expect, this
is super slow.  So I was thinking I could thread it.  Build thefirst
half of the treeview in one thread, build the second half in the other
thread, and put the two together.  Now in the processes that my thread
executes, I'm adding my treenodes.  And when I add breakpoints and
check, they're allegedly there.  But when the page renders, there's no
treeview displayed.
 public void TestThread()
    {
        TreeView tvTemp = new TreeView();
        Thread[] thTempThread = new Thread[2];
        thTempThread[0] = new Thread(new ThreadStart(BuildListPart1));
        thTempThread[1] = new Thread(new ThreadStart(BuildListPart2));
        thTempThread[0].Start();
        thTempThread[1].Start();
    }
    public void BuildListPart1()
    {
        foreach (DataRow drChapter in
Books.dsBookTOC().Tables[2].Rows)  //Get all book chapters
        {
            foreach (DataRow drChapNum in
drChapter.GetChildRows("ChapterTable"))  //Get all chapter numbers
pertaining to this book
            {
                TreeNode trChapter = new
TreeNode(drChapter[5].ToString(), drChapter[3].ToString());
                tvChapterList.Nodes.Add(trChapter);
                foreach (DataRow drSection in
drChapNum.GetChildRows("Section")) //Get all Sections pertaining to
this chapter
                {
                    TreeNode trSection = new
TreeNode(drSection[3].ToString() + " " + drSection[4].ToString(),
drSection[1].ToString());
                    trChapter.ChildNodes.Add(trSection);
                }
            }
        }
    }
And the second function grabs the rest of the list.  Do I have topass
my treeview as a parameterized thread, or something?  Any help is
appreciated.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Top