C#最佳方式每秒运行一个函数,Timer vs Thread?

时间:2015-02-16 16:02:48

标签: c# multithreading timer

我目前正在使用一个线程在控制台应用程序中每秒运行一个函数C#是一个最好的方法吗?正如我问了很多朋友,他们建议使用计时器而不是线程每秒运行一次?如果使用计时器是一个更好的选择,我将如何使用计时器每秒运行一个函数?我环顾四周,但我真的不确定这是否适用于是否以及以正确的方式以我自己的方式进行。那么有人能告诉我答案以及我该怎么做吗?

那么每秒运行它的最佳方法是什么?在您回答之前,让我告诉您,这是每两天运行2天...... 我当前的线程编码

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);
                }
            }
         }
    }
}

3 个答案:

答案 0 :(得分:12)

我使用System.Threading.Timer因为它通常比专用线程使用更少的资源。这是一个例子:

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);
        }
    }
}

这是控制台应用的不错选择。但是,您当然必须记住,回调仍然是在主线程的单独线程上完成的,因此您必须注意同步回调和主线程之间共享的资源和变量。

答案 1 :(得分:4)

您可以查看System.Threading.Timer,它会定期在线程池上执行单个回调,这使得它比线程更准确。 这里代码的外观如何

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
}

答案 2 :(得分:0)

如果您希望任务与任何当前任务并行运行,那么使用线程并不是一个糟糕的选择。虽然,由于任务每秒都要发生,我想这是一项非常小的任务。在这种情况下,最好使用计时器,因为代码较少,更容易理解。

为此,您可以参考系统Timer课程。它有一个例子和一切。
但总的来说,这些都是你要做的事情:

  1. 创建计时器的实例(最好是全局声明它并在Initialize()中初始化它)
  2. 设置间隔(1秒= 1000毫秒)
  3. 启用计时器
  4. 启动它
  5. 或者,您甚至可以根据需要停止