Calling a main thread function?
I'm a noob to C#. So I'll explain my setup so that my question, hopefully, won't sound to ridiculous.
I have two classes: UIForm:System.Windows.Forms.Form and Modeling
The first declares the main thread and is the user interface form, UIForm.
The second holds data that represents(models) the state of a game.
UIForm contains a Modeling object called modeling, Thread
During Initialization in UIForm:
[code]
modeling = new Modeling();
modelingThread = new Thread(new ThreadStart(this.modeling.ModelThread));
modelingThread.Start();
modeling.Updated += new EventHandler(modeling_Updated);
[/code]
modeling_Updated is a function in the UIForm class.
When the modeling thread fires the event, it appears to block until the call to modeling_Updated completes. I placed a five second Thread.sleep statement in modeling_Updated and the UIForm is still responsize. This tells me the main thread is not the one running the code that handles the event, because if I place a 5 second Thread.sleep in a button click event handler, then clicking the button freezes the window up for 5 seconds, because it is the window that is firing the event.
My question: Is the modelingThread basically making a function call "into" the UIForm.modeling_Updated function, or is it simply blocking while the handler executes?
If it is just blocking and waiting for the event handler to complete, then who is executing event handler code. It can't be the main thread, because the sleep statement doesn't freeze the main thread whenever the event is fired by another thread.
I'm thinking that what I really want is to asynchronously fire the event. Should the BeginInvoke work with an event, the same way it works with a delegate? If it is a multicast delegate, do all the functions that have subscribed get started and all run at once, or does the first function run to completion before the second function begins?
What I plan on doing is having the model maintain private data copy, as well as a public data copy. When it completes a loop of calulating and updating the private data, it will lock the data, and flip it to the public data, and fire an event that lets the UIForm know to update it's controls based on this data. I can use a reader write lock easily since both the modelThread and UIForm will need to look at the public data, the modelThread has to see what the data model looked like on the previous time step, as it builds the private data model for the future time step. I'm making a simple game, in case your wondering.
I want the UIForm to update it's controls while the modelThread is concurrently building pivate data for the next time step, and all the while the window is still responsive.
So I'm thinking the event handler(or event handlers in case I have several of them responding to the event later) in UIForm that updates the controls should be fire asynchrounously with BeginInvoke. Does this sound like a good design that will work?
Thanks in advance for any help.
Answers (1)
0
Well,
Normally what i did for parent and child.
Parent - .show()
Child - .showdialog()
So child definetely can close properly by calling this.Close()
But to close parent, execute Application.Exit()
Hope it helps :)
0
Thank you for your reply.
I am currently not setting the Owner propery, but good to know.
A couple of observations:
1.I am using the ShowDialog() method as opposed to the Show() method because I want them to do something in the form or destroy it.
2.The maximize and minimize buttons work fine no problem with them.
3.I am using serial communications very heavily and all of the forms are in while loops for getting data out of serial port (RS232). I created a very simple form fired from a button on the parent form. The close 'X' button worked until I added a while loop similar to the ones in my other child forms. I am using the App.DoEvents method in this loop to catch other events that are firing, but does not seem to work on the close button. Odd how it works with the min/max buttons.
Wondering how that event would get killed just because of the while loop?
Add this simple loop to one of your methods in the five forms you created and see if you have the same results.
while(key_pressed !=0) //wait until user hit a key on the keyboard then go on
Application.DoEvents(); //would think this would catch the close 'X' button

0
If implemented, it will first fire the FormClosing event. If the eventargs.Cancel method is not executed there, then it will go on to close and fire the FormClosed event.
As for closing the child forms, how do you create them? I have a project with two forms. The first form has a button that creates 5 instances of the second form.
private void button1_Click(object sender, EventArgs e)
{
for (int j = 0; j < 5; j++)
{
Form2 frm = new Form2();
frm.Owner = this;
frm.Show();
}
}
If I close the main form, the 5 children are destroyed and the application terminates.
If I remove this line:
frmOwner= this;
... then the children will not be destroyed when I close the main form and the application continues to run. Check the owner property of your child forms. If they are not owned, they will not be destroyed automatically.