Programm soll ewig laufen und alle 5 minuten eine Funktion aufrufen


#1

Hi ich möchte ein Programm schreiben das ewig läuft und alle 5 Minuten eine Funktion auffruft. Gibt es da eine elegantere Lösung als diese:
[csharp] public class Test
{
private static System.Timers.Timer testTimer;

    public static void Main(string[] args)
    {
        Test.run();
    }

    public static void run()
    {
        testTimer = new System.Timers.Timer();
        testTimer.Elapsed += new ElapsedEventHandler(doSomething);
        testTimer.Interval = (1000*60*5);
        testTimer.Enabled = true;

        while (true) { } // go forrest go... :p
    }

    private static void doSomething(object source, ElapsedEventArgs e)
    {
        // mache irgendwas
    }
}[/csharp]

#2

Was daran ist nun nicht elegant?


#3

Fehlt da nicht noch ein sleep in der Schleife? Das verbrät dir ja sonst die ganze CPU.


#4

Hi, naja ich dachte endlosschleifen soll man nicht benutzen, da die wie Antoras angesprochen hat wohl viel Leistung beanspruchen…

Ich suche eine möglichkeit ein Programm ewig laufen zu lassen und alle 5 min eine funktion aufzurufen. Das muss doch auch irgendwie anders gehen als meine gepostete Lösung oder dieser:

[csharp]
while(true)
{
// Mache Irgendwas
Thread.sleep(1000605);
}
[/csharp]


#5

Ganz langsam:

Dir korrekte Lösung ist doch mit dem Timer.

Dort setzt du noch “AutoReset” auf true und hast eine endlosschleife.


#6

Sorry aber ich versteh deinen letzen post nicht ganz…

Das mein zuerst geposteter Code so funktioniert ist mir klar… er funktionier auch ohne “AutoReset = true” wie gewünscht. Ich suche aber nach einer Lösung möglichst ohne die Endlosscheife


#7

Geht nicht, es gibt immer eine Endlosschleife und wenn sie irgendwo im Timer oder gar in der Hardware versteckt ist. Deswegen sollst du ja ein sleep einbauen, dann ist das kein Problem.


#8

Hallo,

statt einer Schleife kann man den Thread auch mit Hilfe eines ResetEvents schlafen legen. Das ist wesentlich performanter.
[csharp]
public static void run()
{
// …

System.Threading.AutoResetEvent ev = new System.Threading.AutoResetEvent(false);
ev.WaitOne();

}
[/csharp]
Gruß
albatros


#9

Ich gebe dir recht das dies wesentlich schöner ist als mit einer Schleifen-Thread.Sleep Kombination.
Aber die schleife braucht er trotzdem, da er es ja immer wieder “endlos” ausführen will. :stuck_out_tongue_winking_eye:

Ja Endlosschleifen, ohne Sleep verbrauchen viel Leistung. Und Schleifen ohne Abbruchbedingung (also “while(true)”) sollte man auch vermeiden.

Ja AutoReset auf true wiederholt das Event immer wieder. Doch sobald die main-Methode fertig ist, ist der Prozess auch schon wieder beendet.
Und er will ihn ja endlos laufen haben.

Hier meine Lösung in Kombination von deinem (eigentlich eh schon richtigen) Code und albatros Hinweise “AutoResetEvent”.
(Kleiner Hinweis Methoden in C# werden UpperCamelCase geschrieben ;P)

[CSHARP] public class Test
{
private static System.Timers.Timer testTimer;

	private static bool shutdown = false;

	private static AutoResetEvent reset = null;

    public static void Main(string[] args)
    {
        Test.Init();
        Test.Run();
    }
	
	public static void Init()
	{
		reset = AutoResetEvent(false);
        testTimer = new System.Timers.Timer();
        testTimer.Elapsed += new ElapsedEventHandler(doSomething);
        testTimer.Interval = (1000*60*5);
	}
	
    public static void Run()
    {
		testTimer.Start();			
		while(!shutdown && reset.WaitOne())
		{
                            // ob der WaitOne() Aufruf in der Bedingung steht oder im Schleifenblock direkt, macht keinen großen Unterschied
                            // mögliche check, log meldungen oder sonstiges durchführen
		}
		testTimer.Stop();
    }

    private static void doSomething(object source, ElapsedEventArgs e)
    {
        // mache irgendwas
		reset.Set();
	}
}[/CSHARP]

#10

Nein, braucht er nicht. Dafür hat er ja den Timer, der regelmäßig auslöst. Deswegen ist es auch ziemlich sinnfrei, regelmäßig reset.Set() im Eventhandler des Timers aufzurufen. Diesen Aufruf kann man nutzen, um das Programm generell abzubrechen. Der “shutdown”-Member ist dann überflüssig.

Gruß
albatros


#11

Ok, verstehe schon. Klar somit würde statt dem Schleifen Konstrukt der einfach Aufruf von reset.WaitOne(); reichen
Bin eher davon ausgegangen das er auch noch in der Schleife möglicherweise Code hat (hier vl weggelassen übersichtshalber).


#12

Vielen dank an albatros genau soetwas habe ich gesucht.