Announcement

Collapse
No announcement yet.

Timerproblem bei zwei Instanzen eines Programms

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Timerproblem bei zwei Instanzen eines Programms

    hi!
    ich hab folgende angabe:
    es soll ein netzwerk-mensch-ärger-dich-nicht programmiert werden. das spielfeld und die kegel sollen in der paint funktion mit ev.graphics.DrawEllipse usw. gezeichnet werden.

    das problem ist jetzt das das ziehen animiert sein soll, d.h. wenn ein kegel von feld 6 auf feld 9 zieht, soll er erst auf 7 dann nach 3s auf 8 und dann nach 3s auf feld 9. ich hab versucht das mit einem timer (aus system.timers.timer) zu lösen. also beim elapsed-event immer um eins weiter. wenn ich jetzt aber zwei instanzen des programms auf einem rechner starte, sieht es so aus als ob sich die timer gegenseitig behindern.

    zur verdeutlichung die schritte in meinem programm
    - zug wird festgelegt (welcher kegel um wieviel felder vorrückt)
    - info an server über diesen zug
    - start des timers
    - bei jedem elapsed um eins weiter

    der server schickt die erhaltene info an den anderen client, worauf dieser ebenfalls die animation startet (also den timer).

    die logik passt, ich hab dasselbe ohne animation (in einer schleife) ausprobiert. reagieren tut es aber trotzdem falsch: der zweite client (der von server die info bekommt) führt die animation durch. der erste aber nicht.

    d.h. beim ersten client wird das elapsed-ereignis nicht ausgelöst.

    hat irgendwer ne ahnung wie man das lösen könnte. (ich hoff ich habs einigermaßen verständlich machen können)

    Jakob

  • #2
    Hallo,

    es gibt gleich 3 Timer-Klassen im .NET-Framework: <br>
    1. System.Windows.Forms.Timer (Komponente auf der Toolbox-Seite Windows Forms)<br>
    2. System.Timers.Timer (Komponente auf der Toolbox-Seite Components) <br>
    3. System.Threading.Timer

    Wenn der Timer die Benutzeroberfläche (Formular) kontrollieren soll, ist die Komponente <b>System.Windows.Forms.Timer</b> die beste Wahl. Solange nicht die Methode DoEvents der Application-Klasse aufgerufen wird, unterbricht das Timer-Ereignis niemals den ausgeführten Code, da der Timer im primären Thread (GUI-Thread) der Anwendung ausgeführt wird.

    Bei <b>System.Timers.Timer</b> wird es etwas komplizierter. Diese Timer-Komponente ist für den sicheren Einsatz in beliebigen Klassen geeignet, die von System.ComponentModel.Component abstammen. Das asynchrone Timer-Ereignis wird in einem von der CLR abgeforderten Arbeits-Thread aus dem Thread-Pool ausgeführt, dieser Timer ist dabei bereits in der Voreinstellung Multitheadfähig. Dies bedeutet aber auch, dass im ausgeführten Timer-Ereignis <b>keine direkten Zugriffe auf Controls/Funktionen der Benutzeroberfläche zulässig sind</b>, solange nicht die Eigenschaft SynchronizingObject genutzt wird

    Comment


    • #3
      also ich hab bei mir im elapsed-ereignis des timers nicht wirklich die benutzeroberfläche editiert. außer einem panel.Invalidate() hab ich auch nicht drauf zugegriffen. das synchronizingObject hab ich auch nicht verwendet (wüsste gar nicht wie das geht).

      am anfang hatte ich den System.Windows.Forms.Timer, mit dem hats aber genausowenig funktioniert. wofür ist den der System.Threading.Timer

      Comment


      • #4
        Hallo,

        &gt;..außer einem panel.Invalidate() hab ich auch nicht drauf zugegriffen..

        das ist doch ein direkter Zugriff, der sogar ein Neuzeichnen des Controls auslöst.

        &gt;Wofür ist den der System.Threading.Timer?

        Die nicht bereits in der Voreinstellung multithreadsichere Klasse dient zur Umsetzung von "Low-Level"-Timerfunktionen, die über vier überladene Konstruktoren erreichbar sind. Das asynchrone Timer-Ereignis wird in einem von der CLR abgeforderten Arbeits-Thread aus dem Thread-Pool ausgeführt

        Comment


        • #5
          Hallo...
          du schriebst am 14.April ...
          <b>Dies bedeutet aber auch, dass im ausgeführten Timer-Ereignis keine direkten Zugriffe auf Controls/Funktionen der Benutzeroberfläche zulässig sind, solange nicht die Eigenschaft SynchronizingObject genutzt wird</B>
          Genau dieses Problem habe ich.
          Ich habe eine Klasse in der ich einen Timer benötige. Also nutze ich den System.Timers.Timer Timer (was für ein Satz). Dann soll im Timer Ereignis eine Methode dieser Klasse aufgerufen werden. Wenn ich dieses dann mache (in der Methode wird auf andere Instanzen zugegriffen) sind die dort verwendeten Instanzen = Nothing.
          Also muss ich erst irgendwie an den "Main Thread" gelangen oder so.
          Aber das SynchronizingObject will mir nicht so recht klar werden.

          Für jede Hilfe wäre ich super dankbar.

          Ralp

          Comment


          • #6
            Hallo,

            das folgende Beispiel stammt aus dem Artikel <i>Comparing the Timer Classes in the .NET Framework Class Library</i> (MSDN Magazin February 2004) und kann unter <i>http://msdn.microsoft.com/msdnmag/issues/04/02/TimersinNET/default.aspx</i> abgerufen werden:
            <pre>
            System.Timers.Timer tmrTimersTimer = <b>new</b> System.Timers.Timer();
            tmrTimersTimer.Interval = 1000;
            tmrTimersTimer.Elapsed += <b>new</b>
            ElapsedEventHandler(tmrTimersTimer_Elapsed);
            tmrTimersTimer.SynchronizingObject = <b>this</b>; <font color="#003399"><i>//Synchronize with </i></font>
            <font color="#003399"><i>//the current form...</i></font>
            tmrTimersTimer.Start();
            •••
            <b>private</b> <b>void</b> tmrTimersTimer_Elapsed(<b>object</b> sender,
            System.Timers.ElapsedEventArgs e) {
            <font color="#003399"><i>// Do something on the UI thread (same thread the form was </i></font>
            <font color="#003399"><i>// created on)...</i></font>
            <font color="#003399"><i>// If we didn't set SynchronizingObject we would be on a </i></font>
            <font color="#003399"><i>// worker thread...</i></font>
            }
            </pre&gt

            Comment


            • #7
              Super... vielen Dank erst mal.
              ABER... ich habe da noch ein Problem. Das ganze funktioniert leider nicht so wenn ich den Timer in einer Klasse (also eine dll) verwenden möchte. Alle Hinweise im Web die ich gefunden habe beziehen sich auh Forms :-(.
              Wenn ich in einer Klasse z.B. <b>tmrTimersTimer.SynchronizingObject = this</b> eingebe bekomme ich was auf die Finger. (Ach übrigens nutze ich VB und kein C#, aber das sollte ja an der Verwendung von SynchronizingObject nix ändern, außer dass ich ier me verwende)

              Hast du noch eine Idee???? Ich bin hier langsam am verzweifeln. Es muss doch irgendwie ein Timer in einer Klasse vernünftig realisierbar sein.

              Ralp

              Comment


              • #8
                Ich habe die Lösung gefunden. (Falls es jemanden interessiert)

                ALSO..
                <PRE>
                'Code der Klasse (meineKlasse()
                Public Sub New(ByVal myObject As Object)
                aTimer = New System.Timers.Timer
                AddHandler aTimer.Elapsed, AddressOf NachbearbeitenEvent
                <b> aTimer.SynchronizingObject = myObject</b>
                end sub

                'Code der Windows Application

                sub irgendwas
                dim neueKlasse as NEW meineKlasse(Me)
                end sub
                </pre>

                beim Instanziieren der Klasse übergebe ich die Win. Application und schon funktioniert der Timer so wie gewünscht.
                Heißt, wenn im Timer Event eine Methode aufgerufen wird, wird diese auch im selben Thread wie die Win. Application ausgeführt.

                Danke für alle Hinweis

                Comment

                Working...
                X