Laden...

Consolenanwendung mit Timer optimieren [Semaphore/Ampel]

Erstellt von uhlealex vor 17 Jahren Letzter Beitrag vor 17 Jahren 8.557 Views
U
uhlealex Themenstarter:in
9 Beiträge seit 2005
vor 17 Jahren
Consolenanwendung mit Timer optimieren [Semaphore/Ampel]

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

X
2.051 Beiträge seit 2004
vor 17 Jahren

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

E
109 Beiträge seit 2006
vor 17 Jahren

hallo,
die endlosschleife ist das problem! versuchs mal mit einem thread

gruß
emmi

Es gibt keine Probleme - nur Herausforderungen!

822 Beiträge seit 2005
vor 17 Jahren

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 😁 😁

S
8.746 Beiträge seit 2005
vor 17 Jahren

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().

6.862 Beiträge seit 2003
vor 17 Jahren

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.

822 Beiträge seit 2005
vor 17 Jahren

Irgendwie überlagern wir uns 😁 😁 😁

S
8.746 Beiträge seit 2005
vor 17 Jahren

Hach, wir sind nur "in tune"... 😉

S
1.047 Beiträge seit 2005
vor 17 Jahren

ä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

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo sheitman,

Threads.Sleep ist aber immer noch Synchronisation für Arme. 🙂

Das Zauberwort heißt Semaphoren (z.B. AutoResetEvent).

herbivore

S
1.047 Beiträge seit 2005
vor 17 Jahren

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? 🙂

49.485 Beiträge seit 2005
vor 17 Jahren

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