Solved

Calling a method with params on a form on a different thread (C#)

Posted on 2004-10-14
10
279 Views
Last Modified: 2012-05-05
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
0
Comment
Question by:mikezat
  • 4
  • 3
  • 2
  • +1
10 Comments
 
LVL 1

Expert Comment

by:jaguarul
Comment Utility
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.
0
 
LVL 51

Expert Comment

by:Julian Hansen
Comment Utility
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
0
 

Author Comment

by:mikezat
Comment Utility
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.NullReferenceException' 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);
0
 
LVL 51

Expert Comment

by:Julian Hansen
Comment Utility
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.
0
 
LVL 1

Accepted Solution

by:
jaguarul earned 375 total points
Comment Utility
julianH is right :)

So, what I think you should read is this link: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemthreadingmanualreseteventclasstopic.asp Basically, you need a way to signal from one thread to the other that the form is created. Therefore, you create the ManualResetEvent in the nonsignaled state before you start the new thread, then in the splash-screen thread you "set" the event right after you instantiated the form. Immediately before the "UpdateCaption" call you should have the blocking call to "WaitOne" on the ManualResetEvent.

I guess you can use whatever synchronization object that mimics the behavior of a semaphore (I don't know the .NET library classes too well).
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 11

Expert Comment

by:pratap_r
Comment Utility
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
0
 
LVL 11

Expert Comment

by:pratap_r
Comment Utility
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
0
 
LVL 51

Expert Comment

by:Julian Hansen
Comment Utility
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?

0
 
LVL 11

Expert Comment

by:pratap_r
Comment Utility
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
0
 
LVL 51

Expert Comment

by:Julian Hansen
Comment Utility
oic - yes that makes sense - need to know when the form has finished doing its thing.
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Suggested Solutions

I know it’s not a new topic to discuss and it has lots of online contents already available over the net. But Then I thought it would be useful to this site’s visitors and can have online repository on vim most commonly used commands. This post h…
This article will show, step by step, how to integrate R code into a R Sweave document
An introduction to basic programming syntax in Java by creating a simple program. Viewers can follow the tutorial as they create their first class in Java. Definitions and explanations about each element are given to help prepare viewers for future …
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now