C# Best Way to run a function every second, Timer

2020-04-05 12:06发布

问题:

I am currently using a thread to run a function every second in a console application C# is a thread the best way to do it? As I have asked a lot of my friends and they have suggested using a timer not a thread for running something every second? If it is a better option to use a timer how would I go about running a function every second using a timer? I have looked around but I am really unsure if that applies to be and if its the right way of going about it in my own way. So can someone tell me the answer and how I can do it?

So what is the best way to run it every second? Before you answer let me just let you know that this is running every second for like 2 days... My current thread coding

namespace Reality.Game.Misc
{
    using Reality;
    using Reality.Communication.Outgoing;
    using Reality.Game.Rooms;
    using Reality.Game.Sessions;
    using Reality.Storage;
    using System;
    using System.Data;
    using System.Threading;

    public static class JobCacheWorker
    {
        private static Thread jWorkerThread;

        public static void HandleExpiration(Session Session)
        {
             using (SqlDatabaseClient client = SqlDatabaseManager.GetClient())
            {
                Session.CharacterInfo.UpdateWorking(client, 0);
            }
        }

        public static void Initialize()
        {
            jWorkerThread = new Thread(new ThreadStart(JobCacheWorker.ProcessThread));
            jWorkerThread.Priority = ThreadPriority.Highest;
            jWorkerThread.Name = "JobCacheWorker";
            jWorkerThread.Start();
        }

        public static void CheckEffectExpiry(Session Session)
        {
            try
            {
                //RunMyCodeHere...
            }
            catch (Exception exception)
            {
                    Console.WriteLine("Exception - JobCacheWorker -> " + exception.Message);
            } 
        }

        private static void ProcessThread()
        {
            while (Program.Alive)
            {
                try
                {
                    foreach (Session Session in SessionManager.Sessions.Values)
                    {
                        if (Session != null && Session.Authenticated && !Session.Stopped)
                        {
                            CheckEffectExpiry(Session);
                            Thread.Sleep(1000);
                        }
                    }
                }
                catch (ThreadAbortException exception)
                {
                    Output.WriteLine("ThreadAbortException - JobCacheWorker -> " + exception.Message);
                }
                catch (ThreadInterruptedException exception2)
                {
                    Output.WriteLine("ThreadInterruptedException - JobCacheWorker -> " + exception2.Message);
                }
            }
         }
    }
}

回答1:

I'd use a System.Threading.Timer because it generally uses less resources than a devoted thread. Here's an example:

using System;
using System.Threading;

namespace Demo
{
    public static class Program
    {
        public static void Main()
        {
            Console.WriteLine("Starting timer with callback every 1 second.");

            Timer timer = new Timer(callback, "Some state", TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));

            Thread.Sleep(4500); // Wait a bit over 4 seconds.

            Console.WriteLine("Changing timer to callback every 2 seconds.");

            timer.Change(TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(2));

            Thread.Sleep(9000);

            timer.Change(-1, -1); // Stop the timer from running.

            Console.WriteLine("Done. Press ENTER");

            Console.ReadLine();
        }

        private static void callback(object state)
        {
            Console.WriteLine("Called back with state = " + state);
        }
    }
}

This is a good choice for a Console app. However, you must of course bear in mind that the callback is still being done on a separate thread from the main thread, so you must be careful about synchronising resources and variables shared between the callback and the main thread.



回答2:

you can take a look at System.Threading.Timer which executes a single callback on a thread pool at a regular intervals which make it more accurate than threads. Here how your code can look like

static void Main(string[] args)
{
    TimerCallback tmCallback = CheckEffectExpiry; 
    Timer timer =  new Timer(tmCallback,"test",1000,1000);
    Console.WriteLine("Press any key to exit the sample");
    Console.ReadLine(); 
}

static  void CheckEffectExpiry(object objectInfo)
{
    //TODO put your code
}


回答3:

If you want the task to run parallel to any current task, then using a thread is not a bad option. Although, since the task is to happen every second, I imagine it is a very small task. In that case, preferably use timer because, lesser code and easier understanding.

To do so, you can refer the System Timer class. It has an example and everything.
But in general, these are the things that you'll be doing:

  1. Create an instance of a timer (Preferably, declare it globally and initialize it in Initialize())
  2. Set the interval (1 second = 1000 millisecond)
  3. Enable the timer
  4. Start it
  5. Optionally, you can even stop it if you want