none
Threads, and refernced class that run Threads RRS feed

  • Question

  • I have a service which create a class A.

    this class A start a thread :

    public class A{ private Thread thread; public A(){ thread = new Thread(Send); thread.Name = "Connector_Send"; thread.Start(); } ~A() { if (thread.IsAlive) thread.Abort(); } public void Stop() //called when service stopped { if (thread.IsAlive) thread.Abort(); } private void Send(){

    B b=new B();

    while(true){

    …….. } }

    class B :

    public class B{
    private Thread thread;
    public B(){
       thread = new Thread(Send2);
                thread.Name = "Connector_Send2";
                thread.Start();
    }
    ~B()
            {
                if (thread.IsAlive) thread.Abort();
            }
            public void Stop() //called when service stopped
            {
                if (thread.IsAlive) thread.Abort();
            }
    private void Send2(){
    
    while(true){
    ……..
    }
    
    }

    in class B, I have a WCF that send message all the time, and a ping every 10 seconds.

    it seems that when class A get stop() event, class B not terminated immediacy as well (I see that the WCF connection is up and for some time).

    maybe my approach not correct?

    maybe the B should be declared not in the thread but rather in the class?

    Monday, July 29, 2019 11:47 AM

All replies

  • So, A starts a thread for A.Send, which in turn creates a B which starts a thread for B.Send.  I assume that, as your text implies, your service message thread calls A.Stop when it gets the stop signal.  But who do you think is going to call B.Stop?  The instance of B is only visible within A.Send, so no outside class can all it.

    As a general rule, Thread.Abort is a poor way to manage thread lifetime.  A MUCH better solution is to use a flag to notify the threads to die, and allow each thread stop cleanly.  For example:

    public class A{
        private Thread thread;
        private bool keep_going;
    
        public A(){
            keep_going = true;
            thread = new Thread(Send);
            thread.Name = "Connector_Send";
            thread.Start();
        }
    
        ~A() {
            Stop();
        }
    
        public void Stop() 
        {
            if (thread.IsAlive) 
            {
                keep_going = false;
                while( thread.IsAlive )
                {
                    Thread.Sleep( 250 );
                }
            }
        }
    
        private void Send(){
            B b=new B();
    
            while(keep_going){
                ...
            }
            b.Stop();
        }
    }
    

    Notice that I have A.Send stop the B thread on its way out.  That should allow everything to clean up properly.


    Tim Roberts | Driver MVP Emeritus | Providenza & Boekelheide, Inc.

    Monday, July 29, 2019 10:58 PM
  • Hi thanks for the explenetation.

    I have noticed that in my current code ~A() is not called why is that?

    Tuesday, July 30, 2019 5:36 AM
  • Hi want 2 Learn, 

    Thank you for posting here.

    Destructors are invoked automatically, and cannot be invoked explicitly.

    You can refer the following reference.

    Destructor never gets called [duplicate]

    Best Regards,

    Xingyu Zhao


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, July 30, 2019 9:29 AM
    Moderator
  • ok,

    where can I read on the relation between a thread and the class it contained (like in my example)

    the relation between objects and so on?

    Thanks!

    Tuesday, July 30, 2019 9:32 AM
  • You don't show us the creation of the A object.  Whoever created the A object ha the responsibility to delete it.  If "A" is a member of your main program's main class, then you might not ever see the destructor get called, because it will be cleaned up while the program is shutting down.


    Tim Roberts | Driver MVP Emeritus | Providenza & Boekelheide, Inc.


    Tuesday, July 30, 2019 6:56 PM
  • There is absolutely no relationship between a thread and a class or object.  In your case, you launch a thread that happens to call a member function of a class.  It's no different than calling a member function inline, except that the call happens to start in a separate thread.  When the thread exits, nothing special will happen to the object.  The thread is just executing a function.

    Someone else has to take the responsibility to manage the lifetime of the object.  That's what I did in my code.  A.Send creates the B object.  A.Send happens to know that creating a B starts a thread, so before it exits, it signals the B thread to stop.  The B object is deleted when the function exits.


    Tim Roberts | Driver MVP Emeritus | Providenza & Boekelheide, Inc.

    Tuesday, July 30, 2019 7:00 PM
  • Hi want 2 Learn, 

    Thanks for your feedback.

    I hope the following reference can help you use threads in C#.

    Threads In C#

    Best Regards,

    Xingyu Zhao


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, July 31, 2019 9:06 AM
    Moderator