web-dev-qa-db-de.com

C # Beste Möglichkeit, jede Sekunde eine Funktion auszuführen, Timer vs Thread?

Ich verwende derzeit einen Thread, um jede Sekunde in einer Konsolenanwendung eine Funktion auszuführen. C # ist ein Thread der beste Weg, dies zu tun? Wie habe ich viele meiner Freunde gefragt und sie haben vorgeschlagen, einen Timer zu verwenden, keinen Thread, um jede Sekunde etwas laufen zu lassen? Wenn es eine bessere Option ist, einen Timer zu verwenden, wie würde ich dann jede Sekunde eine Funktion mit einem Timer ausführen? Ich habe mich umgesehen, aber ich bin mir wirklich nicht sicher, ob das zutrifft und ob es der richtige Weg ist, es auf meine Art zu machen. Kann mir jemand die Antwort sagen und wie ich es schaffen kann?

Was ist der beste Weg, um es jede Sekunde auszuführen? Bevor Sie antworten, lassen Sie mich wissen, dass dies etwa 2 Tage lang jede Sekunde läuft ... Meine aktuelle Thread-Codierung

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

Ich würde ein System.Threading.Timer verwenden, da es im Allgemeinen weniger Ressourcen benötigt als ein dedizierter Thread. Hier ist ein Beispiel:

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

Dies ist eine gute Wahl für eine Konsolen-App. Sie müssen jedoch bedenken, dass der Rückruf immer noch in einem vom Haupt-Thread getrennten Thread ausgeführt wird. Daher müssen Sie beim Synchronisieren von Ressourcen und Variablen, die vom Rückruf und vom Haupt-Thread gemeinsam genutzt werden, vorsichtig sein.

12
Matthew Watson

sie können einen Blick auf System.Threading.Timer werfen, der in einem regelmäßigen Intervall einen einzelnen Rückruf für einen Thread-Pool ausführt, wodurch er genauer ist als Threads. Wie Ihr Code aussehen kann

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

Wenn Sie möchten, dass die Task parallel zu einer aktuellen Task ausgeführt wird, ist die Verwendung eines Threads keine schlechte Option. Da die Aufgabe jedoch im Sekundentakt erfolgen muss, stelle ich mir vor, dass dies eine sehr kleine Aufgabe ist. Verwenden Sie in diesem Fall vorzugsweise einen Timer, da weniger Code und ein leichteres Verständnis erforderlich ist.

Dazu können Sie auf die Klasse System Timer verweisen. Es hat ein Beispiel und alles.
Aber im Allgemeinen werden Sie Folgendes tun:

  1. Eine Instanz eines Timers erstellen (Vorzugsweise global deklarieren und in Initialize () initialisieren)
  2. Stellen Sie das Intervall ein (1 Sekunde = 1000 Millisekunde)
  3. Aktivieren Sie den Timer
  4. Starten Sie es
  5. Optional können Sie es sogar stoppen, wenn Sie möchten
0