Echtzeit!



  • Hallo Leute,

    ich habe einen Thread:

    dieser enhält eine loop!

    ...
    private readonly ManualResetEvent _exitThread;
    
    		void ThreadLoop(object obj)
    		{
    			while (!_exitThread.WaitOne(100))
    			{
    				DoSomething();
    			}
    		}
    ...
    

    nun dauert DoSomething meintenwegen 1 ms! Das bedeutet eine zyklus dauert 101!

    bei 1000 zyklen, hab ich ja schon einen zeit versatz von 1sek!

    Auch wenn ich DoSomething() asyncron aufgerufen wird, gibt es ja dann die gefahr, dass ich einen overflow bekomme da die tausende inovations gemwacht werden die durch async in eingen thread laufen...

    ich müsste die dauer von do something messen, und von so diese vomn zyklus abzeihen.. hmmm..

    oder was gibt noch für ideenen??



  • void ThreadLoop(object obj)
    {
       myTime=clock();//millisekunden
       while(true)
       {
           myTime+=100;//ich hüpfe 100ms weiter
           toWait=myTime-clock();//und so lange müsste ich warten, bis die echte welt nachkömme
           if(toWait>0)//falls ich warten muss (normal)
              if(!_exitThread.WaitOne(toWait))//dann warte ich halt genau so lange, wie nätig, 
              //um den nächsten tick des uhrzeigers zu kriegen
                 break;//und falls ich warte (normal), kann ich abgebrochen werden 
           DoSomething();//egal, wie lange das braucht
       }
    }
    ...
    

    Selbst wenn DoSeomeThing mal ausnahmsweise 1200ms braucht, oder wenn das ganze System mal laggt, weil WinXP beim Reinstecken eines USB-Sticks einen Treiber sucht, das ist mir egal, dann werden halt flugs danach genau so viele DoSomethings nachgeholt, daß im langfristigen Durchschnitt 10 pro Sekunde geschehen.

    Kannste auch anpassen, daß toWait mindestens 900ms ist und dann braucht er halt 20 Läufe, um 2s unerklärlichen Lag aufzuholen, aber keine Sau merkt, daß Dein Compi trickst; trotzdem geht die hypotetische von DoSomething angezeigte Uhr quasi immer genau.

    ich müsste die dauer von do something messen, und von so diese vomn zyklus abzeihen.. hmmm..

    Dann kriegste trotzdem in 24h ein paar Sekunden Abweichung, fürchte ich. Die mag ich nicht.



  • und während er in

    DoSomething();

    ist, kann der loop nich abgebrochen werden!?

    so wirklich hab ich dein beispiel noch nich verstanden, aber danke für die ausführuing;)



  • NullBockException schrieb:

    und während er in
    DoSomething();
    ist, kann der loop nich abgebrochen werden!?

    Dachte, zum Abbrechen von Außen sei genau das _exitThread-Objekt da.

    Soll DoSomething auch selber abbrechen können, darf es entweder den _exitThread setzen oder vielleicht auf natürlichere Weise einen bool zurückliefern. Kommt auf den Rest des Progs an, was angemessener wäre, vermutlich _exitThread. Nee, habs mir überlegt, bool ist besser. Andererseits, wirds mit _exitThread harmonischer, weil alle den selben Weg nehmen. Ach nöö, Fremdbestimmung ist sicher sie Ausnahme, daß z.B. der Dtor der GlobalApp an _exitThread geht, dann ist bool feiner. Ach, egal, Schönheitspreis wird erst wichtig wenn 100+ Klassen zusammenarbeiten.

    NullBockException schrieb:

    so wirklich hab ich dein beispiel noch nich verstanden, aber danke für die ausführuing;)

    Mist, normalerweise würde es völlig klar, wenn Du es man auf Papier nachspielen würdest, den sogenannten "Schreibtischtest" machen. Aber so schnell kann ja kein Mensch schreiben.

    //Start bei 4711Uhr (in Millisekunden)
       myTime=clock();//myTime=4711
       while(true)
       {
           myTime+=100;//myTime=4811
    //zwischenzeitlich 3ms vergangen, clock=4714
           toWait=myTime-clock();//toWait=97!!! automatischer ausgleich. 
           if(toWait>0)//jo, tun wir
              if(_exitThread.WaitOne(toWait))//wartet nur 97ms lang (das ! war wohl falsch, sorry)
    //clock=4811
                 break;//abbrechen, falls in der Zeit ein Signal kam
           DoSomething();//braucht sagen wir mal 34ms, clock=4848
       }
    //und nächst Runde...
       {
           myTime+=100;//myTime=4911
    //zwischenzeitlich 8ms vergangen, clock=4856
           toWait=myTime-clock();//toWait=55!!! automatischer ausgleich. 
           if(toWait>0)//jo, tun wir
              if(_exitThread.WaitOne(55))//wartet nur 55ms lang (das ! war wohl falsch, sorry)
    //clock=4911
                 break;//abbrechen, falls in der Zeit ein Signal kam
    //..und so weiter
    

    Und das verschlockt sich nichtmal, wenn
    //zwischenzeitlich 1200ms vergangen, es holt einfach nach. Es gibt keine Überläufe oder so, weil die Unr, die für DoSomething() gilt, wirklich nur durch das myTime+=100 gemacht wird.



  • Hehe.. volkard.. humor is das wichtigste:) Danke ich schau mir das morgen früh bei firschen Kopf an:) Danke schonmal für deine MÜHE;) 👍 🙂



  • Huhu,

    Das Beispiel leuchtet mir ein;) Um DoSomeThing abrechbar zu machen, müssten deren Aktionen via Statemaschine Kooperatiev Multitasking umgesetzt werden, und sie definiert unterbrechen zu können!

    hmmm....



  • NullBockException schrieb:

    Um DoSomeThing abrechbar zu machen, müssten deren Aktionen via Statemaschine Kooperatiev Multitasking umgesetzt werden, und sie definiert unterbrechen zu können!

    Um DoSomeThing abbrechbar zu machen muss man bloss ein paar Checks ala if (flag) return reinpacken.
    Kompliziertere Umbauten wie die von dir beschriebenen wären nur nötig um DoSomeThing resumable zu machen.



  • @hustbär: hast recht;) und das wort resumable hab ich gesucht;)


Log in to reply