mikezat
asked on
Calling a method with params on a form on a different thread (C#)
Hi! I need to call a method with some parameters
on a form which was created on a different thread.
Here's how I create the form:
// In the Main Thread:
ThreadStart entryPoint = new ThreadStart(ShowSplashForm );
Thread splashFormThread = new Thread(entryPoint);
splashFormThread.Name = "Splash form thread";
splashFormThread.Start();
..................
public static frmSplash m_SplashForm;
public static void ShowSplashForm()
{
m_SplashForm = new frmSplash();
m_SplashForm.ShowDialog();
}
I can see that the form does get created on a new thread called "Splash form
thread"
Now the problem:
The frmSplash form has a public method called
public void UpdateCaption(string newCaption)
How do I call it from the main thread that created this form ?
Please provide the code for this example, not a link to google. I tried searching and examples I found either did not work or were not what I was looking for.
Many Thanks in Advance,
-- Mike
on a form which was created on a different thread.
Here's how I create the form:
// In the Main Thread:
ThreadStart entryPoint = new ThreadStart(ShowSplashForm
Thread splashFormThread = new Thread(entryPoint);
splashFormThread.Name = "Splash form thread";
splashFormThread.Start();
..................
public static frmSplash m_SplashForm;
public static void ShowSplashForm()
{
m_SplashForm = new frmSplash();
m_SplashForm.ShowDialog();
}
I can see that the form does get created on a new thread called "Splash form
thread"
Now the problem:
The frmSplash form has a public method called
public void UpdateCaption(string newCaption)
How do I call it from the main thread that created this form ?
Please provide the code for this example, not a link to google. I tried searching and examples I found either did not work or were not what I was looking for.
Many Thanks in Advance,
-- Mike
You seem to keep a reference (m_SplashForm) to your form. Simply call the method from your main thread. In what way "it doesn't work"? Nothing happens? Crashes? Hangs? You might want to synchronize your two threads, so that you call "UpdateCaption" only after the form is created, but if that was the problem some runtime error would probabily appear.
I agree with jaguarul,
The splash form exists outside of the thread - the thread is only creating and displaying the form so you should be able to simply do a
m_SplashForm.UpdateCaption ( "Almost There ..." )
but as Jaguarul says you need to synchronise your thread with the main thread or you could end up trying to update the Caption with a null m_SplashForm.
Sort of,
WaitForFormToBeCreated
m_SplashForm.UpdateCaption ( "Mostly Done ...")
HTH
The splash form exists outside of the thread - the thread is only creating and displaying the form so you should be able to simply do a
m_SplashForm.UpdateCaption
but as Jaguarul says you need to synchronise your thread with the main thread or you could end up trying to update the Caption with a null m_SplashForm.
Sort of,
WaitForFormToBeCreated
m_SplashForm.UpdateCaption
HTH
ASKER
Hi! Thank you for looking into this. I am getting the following error when I tried this approach. That's why I posted this question here.
"An unhandled exception of type 'System.NullReferenceExcep tion' occurred in WindowsApplication2.exe
Additional information: Object reference not set to an instance of an object."
it occures when calling the splash form's UpdateCaption function:
m_SplashForm.UpdateCaption (pstrMessage);
"An unhandled exception of type 'System.NullReferenceExcep
Additional information: Object reference not set to an instance of an object."
it occures when calling the splash form's UpdateCaption function:
m_SplashForm.UpdateCaption
This means (I think) that your ShowSplashForm code has not finished running and creating the form - m_SplashForm is NULL i.e. the
m_SplashForm = new frmSplash ()
either has not run or failed.
You should do a check on the object before hand to see if it has been instantiated and then either skip or enter some efficient wait state until the object has been created.
One option might be to block the main thread until you get some indication that the SplashThread has created the SplashForm. You could use a synchronisation object (someone please provide an exact C# example) that the main thread waits on and that the ShowSplashForm thread signals right after a successful create of the m_SplashForm object.
If you are unsure post back and I will try and do some code here to demonstrate what I and Jagual were referring to - don't have any off the top of my head.
m_SplashForm = new frmSplash ()
either has not run or failed.
You should do a check on the object before hand to see if it has been instantiated and then either skip or enter some efficient wait state until the object has been created.
One option might be to block the main thread until you get some indication that the SplashThread has created the SplashForm. You could use a synchronisation object (someone please provide an exact C# example) that the main thread waits on and that the ShowSplashForm thread signals right after a successful create of the m_SplashForm object.
If you are unsure post back and I will try and do some code here to demonstrate what I and Jagual were referring to - don't have any off the top of my head.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
or just move the line where you create the form outside of the loop :-)
m_SplashForm = new frmSplash();
ThreadStart entryPoint = new ThreadStart(ShowSplashForm );
Thread splashFormThread = new Thread(entryPoint);
splashFormThread.Name = "Splash form thread";
splashFormThread.Start();
..................
public static frmSplash m_SplashForm;
public static void ShowSplashForm()
{
m_SplashForm.ShowDialog();
}
now it should work! just a one line change :-)
Pratap
m_SplashForm = new frmSplash();
ThreadStart entryPoint = new ThreadStart(ShowSplashForm
Thread splashFormThread = new Thread(entryPoint);
splashFormThread.Name = "Splash form thread";
splashFormThread.Start();
..................
public static frmSplash m_SplashForm;
public static void ShowSplashForm()
{
m_SplashForm.ShowDialog();
}
now it should work! just a one line change :-)
Pratap
if synchronization is what you are looking for then take a look at Events -> manual and autoset
the classes ManualResetEvent and AutoResetEvent should help
basically you create the event object before you start the thread
AutoResetEvent ar=new AutoResetEvent()
Thread th=new Thread(new ThreadStart(ShowSplashForm ));
th.Start();
ar.WaitOne();
//now you can use your m_splashform object
public frmSplash m_SplashForm;
public void ShowSplashForm()
{
m_SplashForm = new frmSplash();
//here
ar.set(); //assuming ar is in scope
m_SplashForm.ShowDialog();
//or here
}
Enjoy!
Pratap
the classes ManualResetEvent and AutoResetEvent should help
basically you create the event object before you start the thread
AutoResetEvent ar=new AutoResetEvent()
Thread th=new Thread(new ThreadStart(ShowSplashForm
th.Start();
ar.WaitOne();
//now you can use your m_splashform object
public frmSplash m_SplashForm;
public void ShowSplashForm()
{
m_SplashForm = new frmSplash();
//here
ar.set(); //assuming ar is in scope
m_SplashForm.ShowDialog();
//or here
}
Enjoy!
Pratap
Pratap,
Looks good - I have one small question though
public void ShowSplashForm()
{
m_SplashForm = new frmSplash();
//here
ar.set(); //assuming ar is in scope
m_SplashForm.ShowDialog();
//or here <----- Is this a good idea?
}
Form would have to be modal - or else what is the purpose of the thread and if it is modal you would have to wait until the form exited before your main loop could proceed - am I correct?
Looks good - I have one small question though
public void ShowSplashForm()
{
m_SplashForm = new frmSplash();
//here
ar.set(); //assuming ar is in scope
m_SplashForm.ShowDialog();
//or here <----- Is this a good idea?
}
Form would have to be modal - or else what is the purpose of the thread and if it is modal you would have to wait until the form exited before your main loop could proceed - am I correct?
i had put that so that a event can be set after the form is closed.. :-) say for example after a dialog result.. probably it should have been //and here. :-)
Pratap
Pratap
oic - yes that makes sense - need to know when the form has finished doing its thing.