Click here to Skip to main content
15,881,882 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
Good Morning all,

I wonder if I might trouble some experienced C# programmers for a piece of methodology advice. Here's my scenario:

I have created a bunch of classes each of which is required by an abstract base class to have a run() method. The run method executes a specific set of tasks and is different for each derived class.
In my main form I have created instances of these classes and grouped them together in a collection. I then iterate through the collection, calling the run() method on each object. This process is done via a background worker.

And here's where my programming methodology query starts. Each of the run() methods generates data, some of which I log to an SQL database and some of which I also put into text boxes on my main form.
When I started with this whole idea my intention was for the collection of objects to raise events when they had generated their data, and this data would be carried along in the event's argument. I would then subscribe to these events in my main form and only update the text boxes that were relevant to the data that had been collected for the object concerned.
However, I experienced problems with this idea because the background worker complained about me trying to update text boxes from a different thread. I was hoping that event driven programming was going to avoid this problem but it didn't.
So what I'm doing now instead is I have a static class that contains some public properties. Each object updates the properties relevant to its data. Each time an object's run method has been executed my background worker raises a progress changed event and then in my main form I update ALL of the text boxes with ALL of the data in my static class. This achieves my goal but is clearly more wasteful because I have to update the entire form each time an object has finished its run() method rather than just updating specific parts of the form for each object.

So I am wondering if I have turned a decent original concept into a bit of a dog's dinner. Perhaps a more experienced C# programmer could set me on the path to a much better way of solving this problem.

Any advice is most welcome.

Thanks,

Brian.

additional information copied from comment below
To clarify, there is one background worker thread which runs a loop. The loop iterates through my collection of objects calling the run() method on each one. Each run() method generates some data, and then on each iteration of the loop I am using the background worker's progress changed event to update all of my text boxes. But really what I wanted was for each object to raise its own event that I could subscribe to on my main form and only update the text boxes that are relevant to each objects data.
Posted
Updated 29-Nov-13 1:15am
v2
Comments
BillWoodruff 29-Nov-13 9:02am    
That's an interesting scenario ... although I am not sure I understand it completely.

What comes to mind, intuitively, is a static Class that functions as a kind of dispatcher, or message hub, that each object/Class instance calls when it needs to update TextBoxes on the Main Form.

Possibly a switch/case statement where the object/Class Type name is used to select which TextBoxes are updated ?

Well, take this with a "grain of salt."
BillWoodruff 1-Dec-13 7:07am    
Upvoted: excellent question, and very thoughtful responses.

UPDATE:

I have now been able to solve this problem myself using advice from the Microsoft MSDN docs here: http://msdn.microsoft.com/en-us/library/ms171728(v=vs.85).aspx

I must admit I am not totally satisfied yet. I am now able to run my hard processing in a background thread and the objects can raise cross-thread events which allow me to deal with stuff on the main form. However, my understanding is limited to 'parrot-fashion' copying of the recommended syntax. This is not acceptable to me but for now, with a deadline looming, I must drop the hot cake and move on.

Once my deadline is out of the way I will revisit this issue, obtain a full understanding of it, and then I'll see if I can document my findings in a manner that will help others who are trying to grapple with it all.
 
Share this answer
 
You initial approach (with backgroubd worker) is correct. You just need to update GUI in GUI thread. Check documentation on InvokeRequred property and Invoke method to learn how to switch to GUI thread.
 
Share this answer
 
Comments
bh_ 30-Nov-13 8:48am    
Thank you everyone for the responses. I was thinking that someone would come along and say "you doofus, you're doing it all wrong!" and then they'd point me in the right direction.

Instead what I've found is there is nothing wrong with my programming and that it's actually not possible to raise events across threads without using some special techniques. The techniques proposed by Adam [Invoke] appear to be what most professionals are proposing as a solution to this problem, hence why I have accepted Adam's solution as the answer to my question.
Here is a good tutorial I found:

http://www.codeproject.com/Articles/23517/How-to-Properly-Handle-Cross-thread-Events-and-Upd
OK so my understanding of the problem is that there are few worker thread fetching some data. Now from this worker thread we want to update some UI element. But if we try to do this directly this will give an error because the worker thread is not able access the UI elements belonging to the main UI thread. I think this link could be useful to find a solution: http://stackoverflow.com/questions/1136399/how-to-update-textbox-on-gui-from-another-thread-in-c-sharp[^]
 
Share this answer
 
Comments
bh_ 29-Nov-13 6:53am    
Thanks for the response Rahul.

To clarify, there is one background worker thread which runs a loop. The loop iterates through my collection of objects calling the run() method on each one. Each run() method generates some data, and then on each iteration of the loop I am using the background worker's progress changed event to update all of my text boxes. But really what I wanted was for each object to raise its own event that I could subscribe to on my main form and only update the text boxes that are relevant to each objects data.

Is this a bit more clear? It's quite difficult to put across in a clear manner.
Rahul Rajat Singh 29-Nov-13 6:55am    
I will try to simulate this in a sample app and then try to see how it can be done.
Nelek 29-Nov-13 7:16am    
That info can be useful for all readers, I copied it to the question

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900