Hallo zusammen,
ich habe eine Consolenanwendung, diese besitzt einen Timer und führt nur bei OnTimedEvent einen Aufruf aus.
Nun mein Problem, die Anwendung lasstet die CPU immer mit über 90% aus und benötigt 8 MB im Speicher, wie kann ich die CPU Auslastung reduzieren ?
Und wenn möglich wie den Speicherbedarf reduzieren ?
hier der source:
[STAThread]
public static void Main(string[] args)
{
int sec = 30;
Timer myT = new Timer((sec*1000));
myT.Start();
myT.Elapsed+=new ElapsedEventHandler(OnTimedEvent);
myT.Enabled=true;
Console.WriteLine("Anwendung aktiv ... Abfrage erfolgt aller " + sec + " sec");
for (;;)
{
// endless loop; wait for event
}
}
danke
Basistechnologien und allgemeine .NET-Klassen
C#-Sprache, Console, Arrays/Collections, DateTime, FileStream & Co, String/Regex, Process/Thread, ResourceManager, DllImport, GC, Reflection ...
Windows-Technologien
System.Windows.Forms-Klassen/Controls, WPF, WWF, Smart Clients, Themes, Databinding, ...
Verschoben
hallo,
die endlosschleife ist das problem! versuchs mal mit einem thread
gruß
emmi
Es gibt keine Probleme - nur Herausforderungen!
Du hast eine ungebremste for Schleife, das könnte es sein. Bremse sie mit System.Threading.Thread.Sleep(//Millisekunden); Und anstelle deinen fors würde ich while(true) verwenden. Und 8MB sind für eine .NET Anwendung nicht viel.
sbertl
//Edit: Mist, zu spät 😁 😁
Original von uhlealex
for (;;) { // endless loop; wait for event } }
Solange du eine Endlosschleife benutzt wird deine Auslastung immer nahezu 100% liegen. Endlosschleifen ohne Warteoperationen konnte man nur auf Nicht-Multi-Tasking-Maschinen ohne Reue einsetzen....also vielleicht noch unter DOS.
Baue die Schleife aus und stelle auf Ereignisse um oder benachrichtige via Sync-Objekte.
Es gibt übrigens Event-Klassen mit so schönen Operationen wie Wait().
Problem ist die Endlosschleife, ist doch klar dass der sich da dumm und dämlich rechnet. Ne ganz einfache Methode um das zu ändern währe mit Thread.Sleep Pausen einzubauen.
Baka wa shinanakya naoranai.
Mein XING Profil.
ähm was fürn sinn macht es nen timer zu benutzen wenn du sowieso im hauptthread ne endlosschleife ablaufen läßt um auf den event zu warten?
es gibt Thread.Sleep(long millis) was den aktuellen Thread für die angegebene Zeit warten läßt, warum benutzt du nicht das und schmeißt den rest über board?
so ne art wie das hier, aber ne abbruchbedingung net vergessen wo er aus der whileschleife wieder raus geht
[STAThread]
public static void Main(string[] args) {
int sec = 30;
Console.WriteLine("Anwendung aktiv ... Abfrage erfolgt aller " + sec + " sec");
while(true) {
Thread.Sleep(sec*1000);
//Inhalt aus OnTimedEvent hier ausführen
}
}
die endlosschleife ist das problem! versuchs mal mit einem thread
ohne die schleife würde das programm ja beendet werden, von daher versteh ich noch zumindest den gedankengang
problem is halt das die schleife aktiv arbeitet die ganze zeit
der timer arbeitet ja schon in einem anderen thread
Hallo sheitman,
Threads.Sleep ist aber immer noch Synchronisation für Arme. 🙂
Das Zauberwort heißt Semaphoren (z.B. AutoResetEvent).
herbivore
Threads.Sleep ist aber immer noch Synchronisation für Arme. 🙂
Das Zauberwort heißt Semaphoren (z.B. AutoResetEvent).
Da ich mich damit garnicht auskenen sonder nur mit der "Armen" Variante hab ich eben diese rein geschrieben 😉
Zumindest dürfte es ein besseres Konzept sein als das ursprüngliche, oder nicht?
Wie chaut denn die "nicht Arme" Variante aus? 🙂
Hallo sheitman,
Semaphore klingt immer so schwer, ist es aber gar nicht. Ich denke, der Code sagt mehr als 1000 Worte:
using System;
using System.Threading;
using System.Timers;
using SystemTimer = System.Timers.Timer;
static class App
{
private static AutoResetEvent _are;
public static void Main (string [] astrArg)
{
Console.WriteLine ("Ampel im Zustand rot erzeugen");
_are = new AutoResetEvent (false);
SystemTimer timer = new SystemTimer ();
timer.Interval = 1000;
timer.Elapsed += TimerElapsed;
timer.Start ();
Console.WriteLine ("Vor (roter) Ampel warten");
_are.WaitOne ();
Console.WriteLine ("Fertig");
}
private static int _iMaleBisKeineLustMehr = 5;
private static void TimerElapsed (Object Sender, ElapsedEventArgs e)
{
if (_iMaleBisKeineLustMehr <= 0) {
Console.WriteLine ("Ampel (kurz) auf grün setzen");
_are.Set ();
return;
}
Console.WriteLine (_iMaleBisKeineLustMehr--);
}
}
Letzendlich sind es diese drei Anweisungen:
_are = new AutoResetEvent (false); // Ampel im Zustand rot erzeugen
_are.WaitOne (); // Vor (roter) Ampel warten
_are.Set (); // Ampel (kurz) auf grün setzen
Bei AutoResetEvent springt die auf grün gesetzte Ampel automatisch und sofort wieder auf rot, sobald der erste vor der Ampel wartende Thread losgelaufen ist. Ein etwaiger zweiter Thread in der Warteschlange würde also zum ersten, müsste aber warten, bis die Ampel erneut (kurz) grün wird. Durch ein _are.Set () läuft also immer nur (maximal) ein Thread weiter.
Bei ManualResetEvent bleibt eine auf grün gesetzte Ampel dagegen solange auf grün, bis sie wieder explizit auf rot gesetzt wird.
Da es im Beispiel nur einen Thread gibt, der vor der Ampel wartet, und außerdem das Programm beendet wird, sobald die Ampel für diesen Thread auf grün gesetzt wurde, würde das Beispiel mit ManualResetEvent genauso funktionieren, wie mit AutoResetEvent.
herbivore
PS: Mit AutoResetEvent.WaitAny kann man warten, bis mindestens eine von mehreren Ampeln auf grün ist. Mit AutoResetEvent.WaitAll kann man warten, bis alle Ampeln auf grün sind.
Suchhilfe: 1000 Worte