web-dev-qa-db-fra.com

C # Meilleure façon de lancer une fonction toutes les secondes, Minuterie par rapport à Thread?

J'utilise actuellement un thread pour exécuter une fonction toutes les secondes dans une application console. C # est-il un thread le meilleur moyen de le faire? Comme j'ai demandé à beaucoup de mes amis et ils ont suggéré d'utiliser une minuterie pas un fil pour exécuter quelque chose à chaque seconde? S'il est préférable d'utiliser une minuterie, comment puis-je exécuter une fonction toutes les secondes à l'aide d'une minuterie? J'ai regardé autour de moi mais je ne suis vraiment pas sûr que cela s'applique et si c'est la bonne façon de procéder à ma manière. Alors, quelqu'un peut-il me dire la réponse et comment je peux le faire?

Alors, quelle est la meilleure façon de l'exécuter toutes les secondes? Avant que vous ne répondiez, laissez-moi vous dire que cela fonctionne chaque seconde pendant environ 2 jours ... Mon codage de thread actuel

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

J'utiliserais un System.Threading.Timer car il utilise généralement moins de ressources qu'un thread dédié. Voici un exemple:

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

C'est un bon choix pour une application console. Cependant, vous devez bien sûr garder à l'esprit que le rappel est toujours effectué sur un thread distinct du thread principal. Vous devez donc faire attention à la synchronisation des ressources et des variables partagées entre le rappel et le thread principal.

12
Matthew Watson

vous pouvez consulter System.Threading.Timer , qui exécute un seul rappel sur un pool de threads à intervalles réguliers, ce qui le rend plus précis que les threads. Voici comment votre code peut ressembler

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
}
4
BRAHIM Kamel

Si vous souhaitez que la tâche s'exécute en parallèle d'une tâche en cours, l'utilisation d'un fil n'est pas une mauvaise option. Bien que, puisque la tâche doit se produire chaque seconde, j'imagine que c'est une tâche très petite. Dans ce cas, utilisez de préférence la minuterie, car un code moins important et une compréhension plus facile.

Pour ce faire, vous pouvez vous référer à System Timer class. Il a un exemple et tout.
Mais en général, voici ce que vous allez faire:

  1. Créer une instance d'un timer (de préférence, déclarez-la globalement et initialisez-la dans Initialize ())
  2. Définir l'intervalle (1 seconde = 1000 milliseconde)
  3. Activer le minuteur
  4. Commence le
  5. Eventuellement, vous pouvez même l'arrêter si vous voulez
0
Sanketh. K. Jain