473,722 Members | 2,397 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

How would i execute it in worker thread ?

153 New Member
Consider the following code in which i add nodes to a treeview control by reading an MS Access database.

Obviously, if I execute in a seperate thread I will get exception about control accessed from a thread other than the one in which it is created.

Now whenever I am adding one node to the tree I could marshel it to the GUI thread like this
Expand|Select|Wrap|Line Numbers
  1. void addnode(string textofnode)
  2. {
  3. }
The problem is that I have got some nodes which are parents of child nodes.
So we create a node and add all children of it and finally add it to treeview.

If i create the children in worker thread and send the parent to GUI thread to add it to the treeview I guess I wont be able to access those children from GUI thread(coz they are cerated in the worker thread)
How would i get around this problem?


Expand|Select|Wrap|Line Numbers
  1.               TreeNode extensions = new TreeNode("Extensions");
  2.                 treeexchange.Nodes.Add(extensions);
  3.  
  4.                 DataTable dtgroups = new DataTable("Groups"); //get groups
  5.                 OleDbDataAdapter adp = new OleDbDataAdapter("select * from t_extensiongroups", @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Application.StartupPath + @"\exchangesandtrunks.mdb;Persist Security Info=False");
  6.                 adp.Fill(dtgroups);
  7.  
  8.                 for (int i = 0; i < dtgroups.Rows.Count; i++)//for all the groups
  9.                 {
  10.                     //create a groupnode with the group name in it
  11.                     TreeNode group = new TreeNode(dtgroups.Rows[i][0].ToString());
  12.  
  13.                     //get no of extensions corresposnding to that group
  14.                     adp = new OleDbDataAdapter("select * from t_extensions where group_name='" + dtgroups.Rows[i]["groups"].ToString() + "'", @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Application.StartupPath + @"\exchangesandtrunks.mdb;Persist Security Info=False");
  15.                     DataTable dtextensions = new DataTable("Extensions");
  16.                     adp.Fill(dtextensions);
  17.  
  18.                     //add all the extension nodes to the groupnode
  19.                     for (int j = 0; j < dtextensions.Rows.Count; j++)
  20.                     {
  21.                         group.Nodes.Add(dtextensions.Rows[j]["name"].ToString() + " (" + dtextensions.Rows[j]["number"].ToString() + ")");
  22.                     }
  23.  
  24.                     //add the group
  25.                     extensions.Nodes.Add(group);
  26.                 }
  27.  
  28.                 //create a trunk node
  29.                 TreeNode trunks = new TreeNode("Trunks");
  30.  
  31.                 //get trunks
  32.                 adp = new OleDbDataAdapter("select connected_trunk,name from t_trunk_lines", @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Application.StartupPath + @"\exchangesandtrunks.mdb;Persist Security Info=False");
  33.                 DataTable dttrunks = new DataTable("Trunks");
  34.                 adp.Fill(dttrunks);
  35.  
  36.                 //add all trunks to the trunk node
  37.                 for (int i = 0; i < dttrunks.Rows.Count; i++)
  38.                 {
  39.                     trunks.Nodes.Add(dttrunks.Rows[i]["name"].ToString() + " (" + dttrunks.Rows[i]["connected_trunk"].ToString() + ")");
  40.                 }
  41.  
  42.                 //add the trunk node
  43.                 treeexchange.Nodes.Add(trunks);
  44.  
  45.                 //add the pbx node
  46.                 treeexchange.Nodes.Add("My PBX");
  47.  
  48.                 treeexchange.Nodes.Add("User");
Jan 6 '09 #1
16 2715
mldisibio
190 Recognized Expert New Member
Your code is unformatted and very difficult to read.

When updating controls on a WinForm from a thread, use a derivative of Control.Invoke to update the control.

A very safe way to update controls on a WinForm is to spawn the thread using a BackgroundWorke r component.

Here is a great article discussing thread updating WinForms:
Threading in Windows Forms.
Jan 6 '09 #2
akshaycjoshi
153 New Member
Here is the formatted code :
Expand|Select|Wrap|Line Numbers
  1.             treeexchange.Nodes.Clear();
  2.                 TreeNode extensions = new TreeNode("Extensions");
  3.                 treeexchange.Nodes.Add(extensions);
  4.  
  5.                 DataTable dtgroups = new DataTable("Groups"); //get groups
  6.                 OleDbDataAdapter adp = new OleDbDataAdapter("select * from t_extensiongroups", @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Application.StartupPath + @"\exchangesandtrunks.mdb;Persist Security Info=False");
  7.                 adp.Fill(dtgroups);
  8.  
  9.                 for (int i = 0; i < dtgroups.Rows.Count; i++)//for all the groups
  10.                 {
  11.                     //create a groupnode with the group name in it
  12.                     TreeNode group = new TreeNode(dtgroups.Rows[i][0].ToString());
  13.  
  14.                     //get no of extensions corresposnding to that group
  15.                     adp = new OleDbDataAdapter("select * from t_extensions where group_name='" + dtgroups.Rows[i]["groups"].ToString() + "'", @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Application.StartupPath + @"\exchangesandtrunks.mdb;Persist Security Info=False");
  16.                     DataTable dtextensions = new DataTable("Extensions");
  17.                     adp.Fill(dtextensions);
  18.  
  19.                     //add all the extension nodes to the groupnode
  20.                     for (int j = 0; j < dtextensions.Rows.Count; j++)
  21.                     {
  22.                         group.Nodes.Add(dtextensions.Rows[j]["name"].ToString() + " (" + dtextensions.Rows[j]["number"].ToString() + ")");
  23.                     }
  24.  
  25.                     //add the group
  26.                     extensions.Nodes.Add(group);
  27.                 }
  28.  
  29.                 //create a trunk node
  30.                 TreeNode trunks = new TreeNode("Trunks");
  31.  
  32.                 //get trunks
  33.                 adp = new OleDbDataAdapter("select connected_trunk,name from t_trunk_lines", @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Application.StartupPath + @"\exchangesandtrunks.mdb;Persist Security Info=False");
  34.                 DataTable dttrunks = new DataTable("Trunks");
  35.                 adp.Fill(dttrunks);
  36.  
  37.                 //add all trunks to the trunk node
  38.                 for (int i = 0; i < dttrunks.Rows.Count; i++)
  39.                 {
  40.                     trunks.Nodes.Add(dttrunks.Rows[i]["name"].ToString() + " (" + dttrunks.Rows[i]["connected_trunk"].ToString() + ")");
  41.                 }
  42.  
  43.                 //add the trunk node
  44.                 treeexchange.Nodes.Add(trunks);
  45.  
  46.                 //add the pbx node
  47.                 treeexchange.Nodes.Add("My PBX");
  48.  
  49.                 treeexchange.Nodes.Add("User");
Jan 7 '09 #3
mldisibio
190 Recognized Expert New Member
I will make two suggestions, but I have not written an example to prove they will work correctly. Let me know if they do not.

Suggestion #1:
  • Instantiate the initial TreeView in the GUI.
  • Pass it as a parameter to a BackgroundWorke r thread (also created in the GUI).
  • Have the thread fill in the nodes (your posted code).
  • Handle the RunWorkerComple ted event to update the actual display of the filled-in TreeView.
  • How To: Run an Operation in the Background.

Suggestion #2:
If you still receive a thread access violation after implementing the above, then add a helper method to your GUI which will clone the nodes created in the thread to the nodes in your GUI TreeView. This can be a simple recusion loop and should run quickly, since you have already performed the data access part in your thread.

However, I truly believe the second step will not be necessary. If you spawn a BackgroundWorke r thread from the GUI, it is guaranteed to execute on the same thread as the GUI itself. It is provided in the Component namespace specifically to eliminate the cross-threading issues associated with WinForms.
Jan 7 '09 #4
r035198x
13,262 MVP
@mldisibio
Actually the task you specify to DoWork is run on a separate thread. That's why the interface remains responsive. The key thing is to make sure that you don't do any GUI updates from DoWork. If intermediate GUI updates are required as in this case then the OnProgressChang ed method should be used which raises the ProgressChanged event. This allows you to queue the interface updates to the UI interface thread.
Jan 8 '09 #5
IanWright
179 New Member
I'm guessing you want something alone the lines of :

Expand|Select|Wrap|Line Numbers
  1. delegate void AddNodeDelegate(string nodeName);
  2.  
  3. void AddNode(string nodeName)
  4. {
  5.    if(treeexchange.InvokeRequired)
  6.    {
  7.       AddNodeDelegate addDelegate = new AddNodeDelegate(AddNode);
  8.       this.Invoke(addDelegate, new object[] { nodeName });
  9.    }   
  10.   else
  11.   {
  12.      this.treeexchange.Nodes.Add(nodeName);
  13.   }
  14. }
  15.  
Your alternative (which I don't like)... is to not do the work in a background thread at all. And put the following in appropriate places to refresh your GUI.

Expand|Select|Wrap|Line Numbers
  1. Application.DoEvents();
Jan 8 '09 #6
mldisibio
190 Recognized Expert New Member
.... And yes, as you say, interface updates must be done via the RunWorkerComple ted event, and optionally the ProgressChanged event if desired.
Jan 8 '09 #7
akshaycjoshi
153 New Member
@mldisibio
If I add nodes in the BackgroundWorke r thread then will I be able to access them from the main GUI thread ?

In some code i am reading the Text of the nodes.
Jan 9 '09 #8
r035198x
13,262 MVP
.... And yes, as you say, interface updates must be done via the RunWorkerComple ted event, and optionally the ProgressChanged event if desired.
Not precisely. The RunWorkerComple ted is used to update the interface when the background task has completed while the ProgressChanged is used for updating the interface while the background task is still running. It's a way for providing intermediate results of the ask to the interface.

EDIT:mldisibio, I'm terribly sorry that I have messed up your response above. I accidentally clicked the edit button when I wanted to click the quote button so in the end I ended up deleting the first and last parts of your post. Only the part that I quoted now remains!
Please feel free to post it again if you wish.
Jan 9 '09 #9
mldisibio
190 Recognized Expert New Member
No problem. For the record I simply corrected my original post, agreeing with your response: the DoWork thread is indeed a separate thread, not the same as the UI thread, but spawing the BackgroundWorke r from the UI guarantees that the worker thread will be correctly marshalled back to the UI thread.
A great link on this subject from Alhahari: Threading in C# - Part 3 - Using Threads
Jan 9 '09 #10

Sign in to post your reply or Sign up for a free account.

Similar topics

2
3968
by: Mark Hoffman | last post by:
All, My application spawns a worker process by calling BeginInvoke with an asynchronous callback method. This callback method is responsible for calling EndInvoke. No problems there; pretty much straight out of MSDN. My question is what happens when my worker thread raises an exception? I can easily catch the exception, but I've noticed that unless my async callback runs and EndInvoke gets called, then the worker thread never gets...
7
2128
by: Jeff Stewart | last post by:
I need a thread to run a subroutine which updates my main form's progress bar. I've properly marshaled all UI updates to the main UI thread, and after the main thread starts the worker thread, it waits for the worker thread to complete by means of a while t.isAlive, sleep(0) mechanism. But when my worker thread calls my UpdateProgressBar routine, which calls Me.Invoke, the invoke call blocks forever. But I can't figure out why the main...
7
2693
by: Charles Law | last post by:
My first thought was to call WorkerThread.Suspend but the help cautions against this (for good reason) because the caller has no control over where the thread actually stops, and it might have a lock pending, for example. I want to be able to stop a thread temporarily, and then optionally resume it or stop it for good.
7
2620
by: hazz | last post by:
What happens if I set the timer interval for a period that is less than the time it will take to process the loop below? Right now my application is returning just a few items in an arraylist to process but the process should scale to 100 or even 1000 loops. If the functions contained within the loop, some of which go out to web services, take an indeterminate amount of time, how do I design my windows service so that if the code takes...
6
5991
by: Joe Jax | last post by:
I have an object that spawns a worker thread to process one of its methods. That method processes methods on a collection of other objects. During this processing, a user may request to cancel the entire operation. I could request abort on the worker thread, but that is a) potentially messy, and b) not guaranteed to take immediate effect anyway. I would rather have some way of allowing the main thread to tell the worker thread that it...
5
3547
by: Soren S. Jorgensen | last post by:
Hi, In my app I've got a worker thread (background) doing some calculations based upon user input. A new worker thread might be invoked before the previous worker thread has ended, and I wan't only one worker thread running at any time (if a new worker thread start has been requested, any running worker thread results will be invalid). I'm using the below method to invoke a new worker thread, but when stress testing this I'm sometimes...
14
6887
by: joey.powell | last post by:
I am using VS2005 for a windows forms application. I need to be able to use a worker thread function to offload some processing from the UI thread. The worker thread will need access to a datagridview on the form. I am using the following code to spawn the worker thread... Thread WorkerThread = new Thread(new ThreadStart(WT_MyFunction)); WorkerThread.IsBackground = true; WorkerThread.Start(); The problem I am having is...I cannot seem...
0
2473
by: =?Utf-8?B?aGVyYmVydA==?= | last post by:
I read from a serialport using a worker thread. Because the worker thread t does not loop often, I cannot wait to terminate the worker thread using a boolean in the While condition. So I have a StopReader() method that simply aborts the worker thread (is there a better way for the above situation?). The StopReader creates an ObjectDisposedException when calling t.Abort(). WHY? Public Sub StopReader()
4
2056
by: dgleeson3 | last post by:
Hello all Yes I know its been done before, but something silly is killing me on this. I have the standard progress bar and worker thread scenario with progress of the worker thread being fed back to the main UI and displayed on the progress bar. I have a delegate and am using BeginInvoke. But the progress bar is not updating.
0
8739
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9384
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9238
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9157
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9088
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
4762
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3207
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2602
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2147
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.