Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / New Users / June 2007

Tip: Looking for answers? Try searching our database.

C# threading, events and main thread.

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
djdouma - 16 Jun 2007 13:38 GMT
I've been working on this one for a couple of days, and am completly
at my wits end.  Is there some method for executing a function or
event in the main thread, when called from a 'worker' thread?  I
understand how it works in the Windows forms world, but what about an
application with no GUI?

I provided example code and the output below.  What I'm looking for is
to have the prog_ShowPopUpEvent method executed by the main thread.

Thanks!

Output:
MAIN THREAD : Sleeping for 1 second
MAIN THREAD : Sleeping for 1 second
MAIN THREAD : Sleeping for 1 second
MAIN THREAD : Sleeping for 1 second
MAIN THREAD : Sleeping for 1 second
TIMER THREAD : timer elapsed
TIMER THREAD : fire show pop up event
TIMER THREAD : show pop up event fired
Main thread exiting.

Code:
using System;
using System.Threading;

namespace ConsoleApplication1
{
   public class Program
   {
       private bool _running = false;
       private event EventHandler ShowPopUpEvent;

       [STAThread]
       public static void Main()
       {
          Program prog = new Program();
          prog.Run();
       }

       private void Run()
       {
           this.ShowPopUpEvent += new
EventHandler(prog_ShowPopUpEvent);
           Thread.CurrentThread.Name = "MAIN THREAD";

           System.Timers.Timer checksTimer = new
System.Timers.Timer();

           //Elapse every 5 seconds
           checksTimer.Interval = 5000;
           checksTimer.Elapsed +=new
System.Timers.ElapsedEventHandler(checksTimer_Elapsed);
           checksTimer.Enabled = true;

           this._running = true;

           do
           {
               Console.WriteLine("{0} : Sleeping for 1 second",
Thread.CurrentThread.Name);
               Thread.Sleep(1000);
           }
           while (this._running);
           Console.WriteLine("Main thread exiting.");
       }

       private void prog_ShowPopUpEvent(object sender, EventArgs e)
       {
           Console.WriteLine("{0} : show pop up event fired",
Thread.CurrentThread.Name);
           this._running = false;
       }

       void checksTimer_Elapsed(object sender,
System.Timers.ElapsedEventArgs e)
       {
           if (Thread.CurrentThread.Name == null)
               Thread.CurrentThread.Name = "TIMER THREAD";

           Console.WriteLine("{0} : timer elapsed",
Thread.CurrentThread.Name);

           //Perform a bunch of checks
           if (true == false)
           {
           }
           else
           {
               //Show the popup window
               OnShowPopup();
           }
       }

       private void OnShowPopup()
       {
           if (ShowPopUpEvent != null)
           {
               Console.WriteLine("{0} : fire show pop up event",
Thread.CurrentThread.Name);
               ShowPopUpEvent(this, new EventArgs());
           }
       }
   }
}
Peter Duniho - 16 Jun 2007 18:23 GMT
> I've been working on this one for a couple of days, and am completly
> at my wits end.  Is there some method for executing a function or
> event in the main thread, when called from a 'worker' thread?

Yes.  Use the Control.Invoke() method.

I don't know what version of Visual Studio you're using, if any, but I'm  
using VS 2005 and if I tried to execute the code you posted, I'd get the  
"cross-thread call" MDA exception, with a clickable link to a help topic  
that provides very nice details regarding how to do this.

Pete
Jon Skeet [C# MVP] - 16 Jun 2007 19:16 GMT
> > I've been working on this one for a couple of days, and am completly
> > at my wits end.  Is there some method for executing a function or
> > event in the main thread, when called from a 'worker' thread?
>
> Yes.  Use the Control.Invoke() method.

There are no controls to invoke in this case though - it's a console
application.

> I don't know what version of Visual Studio you're using, if any, but I'm  
> using VS 2005 and if I tried to execute the code you posted, I'd get the  
> "cross-thread call" MDA exception, with a clickable link to a help topic  
> that provides very nice details regarding how to do this.

No, you wouldn't - that applies to Windows Forms, not console
applications.

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too

Peter Duniho - 16 Jun 2007 19:33 GMT
> No, you wouldn't - that applies to Windows Forms, not console
> applications.

Are you trying to tell me that I should not be trying to answer questions  
after staying up almost all night with a sick kid?

Sheesh...picky, picky.

(Yes, I completely missed the fact that this is a console  
application...sorry)
Jon Skeet [C# MVP] - 16 Jun 2007 19:42 GMT
> > No, you wouldn't - that applies to Windows Forms, not console
> > applications.
>
> Are you trying to tell me that I should not be trying to answer questions  
> after staying up almost all night with a sick kid?

LOL.

> Sheesh...picky, picky.
>
> (Yes, I completely missed the fact that this is a console  
> application...sorry)

If I had to pay someone every time I'd come up with a bad answer for
whatever reason, I'd be on the street...

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too

Ben Voigt [C++ MVP] - 16 Jun 2007 19:47 GMT
>> > No, you wouldn't - that applies to Windows Forms, not console
>> > applications.
[quoted text clipped - 11 lines]
> If I had to pay someone every time I'd come up with a bad answer for
> whatever reason, I'd be on the street...

So would I.  In fact, isn't that the true meaning of "MVP"?
Jon Skeet [C# MVP] - 16 Jun 2007 19:17 GMT
> I've been working on this one for a couple of days, and am completly
> at my wits end.  Is there some method for executing a function or
> event in the main thread, when called from a 'worker' thread?  I
> understand how it works in the Windows forms world, but what about an
> application with no GUI?

You'd need to have your own equivalent of the message pump - basically
the main thread would just have to be waiting to be given work to do.
You can't interrupt a running thread to give it a different task.

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too

Ben Voigt [C++ MVP] - 16 Jun 2007 19:34 GMT
>> I've been working on this one for a couple of days, and am completly
>> at my wits end.  Is there some method for executing a function or
[quoted text clipped - 5 lines]
> the main thread would just have to be waiting to be given work to do.
> You can't interrupt a running thread to give it a different task.

So the key question is, what is the main thread doing when you want to give
it a function to execute?  Can you have it periodically poll a list of
delegates (don't forget locking, or use a thread-safe linked list)?
djdouma - 17 Jun 2007 04:04 GMT
> "Jon Skeet [C#MVP]" <s...@pobox.com> wrote in messagenews:MPG.20de3985ba15021724b@msnews.microsoft.com...
>
[quoted text clipped - 18 lines]
>
> - Show quoted text -

I suppose the main thread could poll a list of delegates to see if it
has work to do.  Would you be able to provide a sample of this?  Would
the delegate list just be using an ArrayList or a typed List<T>?  I
was looking for similar functionality to the Invoke / BeginInvoke used
in Windows Forms.  The reason for the do while with a sleeping thread
is just so the application doesn't exit. :D  The timer checks if
certian conditions have exist (Certian reg values to exist, files to
exist, etc), and notify the main thread.  The main thread will then
respond according to the condition that was met.  In some cases, it
may need to display a pop-up, in others, it may need to start a
process.
Ben Voigt [C++ MVP] - 17 Jun 2007 04:15 GMT
>> "Jon Skeet [C#MVP]" <s...@pobox.com> wrote in
>> messagenews:MPG.20de3985ba15021724b@msnews.microsoft.com...
[quoted text clipped - 31 lines]
> may need to display a pop-up, in others, it may need to start a
> process.

Use an Event to wake the main thread after adding to the list, instead of
polling.

I would certainly recommend using a generic LinkedList<T>.  ArrayList is the
best that could be done in C# 1.0, since C# 2.0 came out the generic
collections are better in every way.  Or you could just use a delegate
variable with the += operator.

Surround all access to the delegate list with a lock block for
thread-safety... you can lock on the list if you use a LinkedList, or on
typeof(MyMainClass) if using a static delegate variable.
Peter Duniho - 17 Jun 2007 18:59 GMT
> I suppose the main thread could poll a list of delegates to see if it
> has work to do.  Would you be able to provide a sample of this?  Would
> the delegate list just be using an ArrayList or a typed List<T>?  I
> was looking for similar functionality to the Invoke / BeginInvoke used
> in Windows Forms.

Ben has given good suggestions for how to implement this yourself.  
There's nothing built in to .NET that provides for this directly, a la  
Invoke().

> The reason for the do while with a sleeping thread
> is just so the application doesn't exit. :D  The timer checks if
[quoted text clipped - 3 lines]
> may need to display a pop-up, in others, it may need to start a
> process.

In addition to what Ben wrote, regarding implementing a delegate queue,  
your reply begs the question: if all the main thread is doing is waiting  
for some other thread to do work, why not just do the work on the main  
thread?

Basically, we can answer the question (and Ben has) of how to accomplish  
the very specific goal stated (have one thread pass a delegate to another  
thread for execution).  But it still appears that there's no need to do  
that.  It's not usually necessary for a given piece of code to execute on  
a particular thread, and it's not clear what it is that the main thread in  
your application is doing that prevents it from simply being the thread to  
do whatever the other thread is doing anyway.

It seems to me that there are two open questions yet:

    1) Why can't the code running on the worker thread simply be executed  
in the main thread?

    2) Why can't the code that you want executed on the main thread just  
be executed in the worker thread?

You don't have to answer these question here, of course.  But if you want  
the best advice, you should.  And at a minimum, you should at least  
consider them with respect to the design of your code, because on the face  
of it there are some odd things about the design of your code, at least  
based on the small peek we have gotten of it.

Pete
Peter Duniho - 16 Jun 2007 19:42 GMT
> I've been working on this one for a couple of days, and am completly
> at my wits end.  Is there some method for executing a function or
> event in the main thread, when called from a 'worker' thread?  I
> understand how it works in the Windows forms world, but what about an
> application with no GUI?

For what it's worth, now that I have been directed back onto the correct  
track...

Can you explain in more detail _why_ you want the handling of the event to  
occur on the main thread?  The reason this is such a big deal with a Form  
is because of the restrictions Windows has with respect to windows and  
their relationship to the thread that created a window.  But as far as I  
know, there's not a similar issue with the console output.

(In my defense, it's this lack of an issue with respect to console  
applications, as well as the "ShowPopUp" name of your event handler, that  
made me assume you were talking about Forms even though you specifically  
said you weren't).

Pete

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.