why can't i start/stop separate threads inside of same block?
-
hey everyone... i've probably missed something very important, and just don't know it. the reason: i'm trying to populate 2 treeviews from 2 separate threads with separate data in each, both trees are pretty slow to load so i need the threads, else i lock up the ui for about 10sec. I also have to refresh the trees throughout the progress so i've had to build the threads the way i have so i can access it later. the problem: if i try to invoke both threads in the same form_load block i end up with 2 trees with the same data. if i invoke them separately (comment one or the other out) i have proven that the code works properly for both, so it leads me to believe that i've either done something terribly wrong or i just can't do what i'm trying to do........ any ideas? here is the code:
Thread PcTree, pclist,EmpTree,emplist;
MethodInvoker CallCompList, CallEmpList; private void Form1\_Closing(object sender, System.ComponentModel.CancelEventArgs e) { // pclist = new Thread(new ThreadStart(initializePcTree)); // pclist.Start(); // emplist = new Thread(new ThreadStart(initializeEmpTree)); // emplist.Start(); switch (tabControl1.SelectedIndex) { case 0: initializePcTree(); break; case 4: initializeEmpTree(); break; } } private void initializePcTree() { PcTree = new Thread(new ThreadStart(PopComputerList)); PcTree.IsBackground = true; PcTree.Name = "PcTree"; PcTree.Start(); }
-
hey everyone... i've probably missed something very important, and just don't know it. the reason: i'm trying to populate 2 treeviews from 2 separate threads with separate data in each, both trees are pretty slow to load so i need the threads, else i lock up the ui for about 10sec. I also have to refresh the trees throughout the progress so i've had to build the threads the way i have so i can access it later. the problem: if i try to invoke both threads in the same form_load block i end up with 2 trees with the same data. if i invoke them separately (comment one or the other out) i have proven that the code works properly for both, so it leads me to believe that i've either done something terribly wrong or i just can't do what i'm trying to do........ any ideas? here is the code:
Thread PcTree, pclist,EmpTree,emplist;
MethodInvoker CallCompList, CallEmpList; private void Form1\_Closing(object sender, System.ComponentModel.CancelEventArgs e) { // pclist = new Thread(new ThreadStart(initializePcTree)); // pclist.Start(); // emplist = new Thread(new ThreadStart(initializeEmpTree)); // emplist.Start(); switch (tabControl1.SelectedIndex) { case 0: initializePcTree(); break; case 4: initializeEmpTree(); break; } } private void initializePcTree() { PcTree = new Thread(new ThreadStart(PopComputerList)); PcTree.IsBackground = true; PcTree.Name = "PcTree"; PcTree.Start(); }
You cannot call methods on Controls created on another thread. T do this, you have to use the Invoke methods of the Controls. See this: http://blogs.wwwcoder.com/amachin/archive/2004/12/15/1146.aspx[^] EDIT: Sorry, misread your article. You are using BeginInvoke, this should work. Anyway, you probably should read the article linked above, it may solve your issue. -------- "I say no to drugs, but they don't listen." - Marilyn Manson -- modified at 12:06 Friday 20th January, 2006
-
hey everyone... i've probably missed something very important, and just don't know it. the reason: i'm trying to populate 2 treeviews from 2 separate threads with separate data in each, both trees are pretty slow to load so i need the threads, else i lock up the ui for about 10sec. I also have to refresh the trees throughout the progress so i've had to build the threads the way i have so i can access it later. the problem: if i try to invoke both threads in the same form_load block i end up with 2 trees with the same data. if i invoke them separately (comment one or the other out) i have proven that the code works properly for both, so it leads me to believe that i've either done something terribly wrong or i just can't do what i'm trying to do........ any ideas? here is the code:
Thread PcTree, pclist,EmpTree,emplist;
MethodInvoker CallCompList, CallEmpList; private void Form1\_Closing(object sender, System.ComponentModel.CancelEventArgs e) { // pclist = new Thread(new ThreadStart(initializePcTree)); // pclist.Start(); // emplist = new Thread(new ThreadStart(initializeEmpTree)); // emplist.Start(); switch (tabControl1.SelectedIndex) { case 0: initializePcTree(); break; case 4: initializeEmpTree(); break; } } private void initializePcTree() { PcTree = new Thread(new ThreadStart(PopComputerList)); PcTree.IsBackground = true; PcTree.Name = "PcTree"; PcTree.Start(); }
private void PopComputerList()
{
CallCompList = new MethodInvoker(CompList);
de = new DirectoryEntry("LDAP://~.com");
ds = new DirectorySearcher(de);
ds.Filter = ("(~)");
this.BeginInvoke(CallCompList);
}
private void PopEmpList()
{
CallEmpList = new MethodInvoker(EmpList);
de = new DirectoryEntry("LDAP://~.com");
ds = new DirectorySearcher(de);
ds.Filter = ("(~)");
this.BeginInvoke(CallEmpList);
}Look what you're doing here with the
de
andds
variables. You're using a class scopedde
andds
variables. DON'T! Each thread should create and use it's own set of Directory objects scoped within the methods themselves. What's happening is that when you launch your first thread, it sets up thede
andds
variables to perform a search. While that setup and search is taking place, you launch another thread that, low and behold, reassigns new DirectorySearcher and DirectoryEntry objects to the very samede
andds
variables you just setup in your previous thread. Global variables - bad idea... RageInTheMachine9532 "...a pungent, ghastly, stinky piece of cheese!" -- The Roaming Gnome -- modified at 12:26 Friday 20th January, 2006 -
private void PopComputerList()
{
CallCompList = new MethodInvoker(CompList);
de = new DirectoryEntry("LDAP://~.com");
ds = new DirectorySearcher(de);
ds.Filter = ("(~)");
this.BeginInvoke(CallCompList);
}
private void PopEmpList()
{
CallEmpList = new MethodInvoker(EmpList);
de = new DirectoryEntry("LDAP://~.com");
ds = new DirectorySearcher(de);
ds.Filter = ("(~)");
this.BeginInvoke(CallEmpList);
}Look what you're doing here with the
de
andds
variables. You're using a class scopedde
andds
variables. DON'T! Each thread should create and use it's own set of Directory objects scoped within the methods themselves. What's happening is that when you launch your first thread, it sets up thede
andds
variables to perform a search. While that setup and search is taking place, you launch another thread that, low and behold, reassigns new DirectorySearcher and DirectoryEntry objects to the very samede
andds
variables you just setup in your previous thread. Global variables - bad idea... RageInTheMachine9532 "...a pungent, ghastly, stinky piece of cheese!" -- The Roaming Gnome -- modified at 12:26 Friday 20th January, 2006Good point Dave, I think i picked up that bad habit from those redim-ing vb guys i work with :doh: problem fixed! string Beautiful; Beautiful = "ignorant"; label1.Text = "The world is full of " + Beautiful +" people."; Why is common sense such an un-common comodity?