How can I for timers who were initiated by a task c#

Asked

Viewed 183 times

0

Hello, I’m trying to understand a situation but so far I haven’t been able to solve it. Imagine that we have an X class that has a timer that is started by the constructor. Now imagine that this same class is instantiated inside a thread.

Doing some tests on my code I realized that if I give Ispose in the thread, the timer running in the class will continue running. I tried to create a list and try to stop the timer of the objects but it still didn’t work.

An example of the problem in a c console solution# -

public class Phone
    {
        private static System.Timers.Timer aTimer;

        private int ID;

        public Phone(int ID)
        {
            this.ID = ID;
        }

        public void Start()
        {
            aTimer = new System.Timers.Timer(2000);
            aTimer.Elapsed += OnTimedEvent;
            aTimer.AutoReset = true;
            aTimer.Enabled = true;
        }

        public void Stop()
        {
            aTimer.Stop();
            aTimer.Dispose();
        }

        private void OnTimedEvent(Object source, ElapsedEventArgs e)
        {
            Console.WriteLine("Radio ID : " + ID);
            Console.Write(" Launch thread: {0}", Thread.CurrentThread.ManagedThreadId);
        }
    }

    class Program
    {
        static void Main()
        {
            List<Task> list = new List<Task>();

            for (int i = 0; i < 10; i++)
            {
                Phone A = new Phone(i);


                list.Add(Task.Factory.StartNew(() => {

                    A.Start();

                }));


            }

            Console.ReadKey();
            Console.WriteLine(" STOPPING THREAD");

            for (int i = 0; i < 10; i++)
            {
                list[i].Dispose();
            }

            Console.ReadKey();
        }

    }
}

1 answer

0

You have prompted the object within the main thread, not in the thread you are giving Ispose... you have just created another thread to call start... enfin...

in this situation you could put your Phone class to implement the Idisposable interface and then implement the Dispose method of your class, in addition to that, if your Phone should work asynchronously, you can put the Task inside it, which avoids external implementation in addition to avoiding the timer. I made an example code:

Class Phone

public class Phone : IDisposable
{
    private int ID;
    private Task t;
    private bool running = false;
    public Phone(int ID)
    {
        this.ID = ID;
    }

    public void Start()
    {
        running = true;
        Console.WriteLine("Radio Start : " + ID);
         t = Task.Factory.StartNew(() =>
            {
                while (running)
                {
                    Console.WriteLine("Radio ID: {0} Running in Thread {1}", ID, Thread.CurrentThread.ManagedThreadId);
                    Thread.Sleep(1000);
                }
            });
    }

    public void Stop()
    {
        if (running)
        {
            running = false;
            Console.WriteLine("Radio Stopping : " + ID);
            while (t.Status == TaskStatus.Running)
            {
                Console.WriteLine("Parando thread...: " + Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(500);
            }
            Console.WriteLine("Radio Stopped : " + ID);
            t.Dispose();
        }
        else
        {
            Console.WriteLine("Radio not Running : " + ID);
        }
    }

    public void Dispose()
    {
        this.Stop();
        Console.WriteLine("Radio Disposed : " + ID);
    }
}

Execution:

class Program
{
    static void Main(string[] args)
    {
        List<Phone> phones = new List<Phone>();

        for (int i = 0; i < 10; i++)
        {
            Phone obj = new Phone(i);
            phones.Add(obj);
            obj.Start();
        }

        Console.ReadKey();
        Console.WriteLine("STOPPING THREAD");

        foreach (Phone p in phones)
        {
            p.Dispose();
        }

        Console.WriteLine("All Threads stopped");
        Console.ReadKey();

    }
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.