We help IT Professionals succeed at work.

C# timer

blue-coder
blue-coder used Ask the Experts™
on
here's my situation: I need to call a function after a certain amount of time passes (user determines length of time using a trackbar) we will refer to this value as X.  however, I also need to put a limit on how long the function can run (say about 5 seconds) this value is Y.  so the end result would be that the function would be called every X seconds, but once the function was running if it ran Y seconds then it would be interupted.... now that I have typed this it seems a bit confusing, feel free to ask for more details.  thank you
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®

Commented:
are you using Timer feature?

you can create two Timers.  you can set 1st timer when it needs to start/.stop, and what interval that you want to run. and have another timer tick in at the end result at your function call.

Commented:
Well he'll be using timers the way you said, but the hard part is providing a mechanism for being able to interrupt an executing function.  The only good way that I can think of to do this is to execute the function in a separate thread and then interrupt that thread from the main thread when the maximum run-time timer elapses.  The pseudo-code would be:
In your main class,
-Create your function to call.
-Create thread which calls your function (but don't start it!)
-Create your first timer, the one that counts down until executing the function.
-Create your second timer, the one that counts how long the function can execute.
-Make the first timer's elapsed event start your thread (which will basically run your function in the background).  Also make it disable itself so the timer does not fire again yet.
-Start your second timer.
-Make your second timer's elapsed function interrupt the thread, and stop itself.  It should restart the first timer so this can all happen again after that timer's interval as you requested.
Here's links on timer creation and thread interruption :)
//Timer creation:
http://www.codeguru.com/csharp/sample_chapter/article.php/c7763 
//Thread interrupt:
http://msdn.microsoft.com/en-us/library/system.threading.thread.interrupt.aspx
 Good luck man,
-w00te
Mike TomlinsonHigh School Computer Science, Computer Applications, Digital Design, and Mathematics Teacher
Top Expert 2009

Commented:
What is the nature of the function that needs to be run?  Can it check the time to see if it has exceeded the limit or are you envisioning HARSHLY KILLING a thread to kill the function?

Author

Commented:
wow, thank you all for the quick reponse.  looking over your comments it seems that I was right to seek advice, it seems complicated.  in response to Idle Mind i don't think it would be a problem to kill the thread, the function basically just waiting to recieve a signal from another device.
Commented:
Here's a sample.  Note that the synchronization code is pretty sensitive, so when you make changes, test often to track them.

        System.Timers.Timer t1 = new System.Timers.Timer();
        System.Timers.Timer t2 = new System.Timers.Timer();
        bool t2Expired = false;
        bool taskCompleted = false;
        const int X = 500;
        const int Y = 100;
        List<int> theList = new List<int>();

        void test27()
        {
            int nbrTimes = 10;

            // Add event handlers
            t1.Elapsed += new System.Timers.ElapsedEventHandler(t1_Elapsed);
            t2.Elapsed += new System.Timers.ElapsedEventHandler(t2_Elapsed);

            Debug.Assert(Y < X, "Time for task should be less than interval between calls");
            t1.Interval = X;
            t2.Interval = Y;

            t1.Enabled = true;

            // Runs the timer, and raises the event.
            while (nbrTimes > 0)
            {
                if (taskCompleted)
                {
                    taskCompleted = false;
                    if (--nbrTimes > 0)
                    {
                        t1.Interval = X - Y;        // Y has elapsed running the task; total since last time will be X
                        t1.Enabled = true;
                    }
                }

                // Processes all the events in the queue.
                Application.DoEvents();
            }

            // Display the results
            string s = "";
            for (int i = 0; i < theList.Count; ++i)
            {
                if (s.Length > 0) s += "\n";
                s += theList[i];
            }
            MessageBox.Show(s, "Results");
        }

        int TheTask()
        {
            int n = 0;
            while (!t2Expired) ++n;
            return n;
        }

        void t1_Elapsed(object source, System.Timers.ElapsedEventArgs e)
        {
            // Suspend this timer
            t1.Enabled = false;

            // Start second timer
            t2Expired = false;
            t2.Enabled = true;

            // Invoke the task
            taskCompleted = false;
            theList.Add(TheTask());
            taskCompleted = true;
        }

        void t2_Elapsed(object source, System.Timers.ElapsedEventArgs e)
        {
            t2.Enabled = false;
            t2Expired = true;
        }

Open in new window

Mike TomlinsonHigh School Computer Science, Computer Applications, Digital Design, and Mathematics Teacher
Top Expert 2009

Commented:
Another one...
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            trackBar1.Value = 10;
            trackBar2.Value = 5;
            trackBar1_ValueChanged(null, null);
        }

        private void trackBar1_ValueChanged(object sender, EventArgs e)
        {
            trackBar2.Maximum = trackBar1.Value - 1;
            timer1.Stop();
            timer1.Interval = (int)TimeSpan.FromSeconds((double)trackBar1.Value).TotalMilliseconds;
            timer1.Start();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            System.Threading.Thread T = new System.Threading.Thread(new System.Threading.ThreadStart(Foo));
            System.Windows.Forms.Timer Tmr = new Timer();
            Tmr.Interval = (int)TimeSpan.FromSeconds((double)trackBar2.Value).TotalMilliseconds;
            Tmr.Tick += new EventHandler(Tmr_Tick);
            Tmr.Tag = T;
            T.IsBackground = true;
            T.Start();
            Tmr.Start();
        }

        void Tmr_Tick(object sender, EventArgs e)
        {
            System.Windows.Forms.Timer Tmr = (Timer)sender;
            System.Threading.Thread T = (System.Threading.Thread)Tmr.Tag;
            Tmr.Stop();
            Console.WriteLine("Aborting Thread...");
            T.Abort();
        }

        private void Foo()
        {
            Console.WriteLine("Thread Started....");
            while (true)
            {
                System.Threading.Thread.Sleep(1000);
                Console.WriteLine(DateTime.Now.ToString());
            }
        }

    }

}

Open in new window