Laden...

Timer für einem Windows Service

Erstellt von bhelbig vor 14 Jahren Letzter Beitrag vor 14 Jahren 2.528 Views
B
bhelbig Themenstarter:in
135 Beiträge seit 2006
vor 14 Jahren
Timer für einem Windows Service

Hi, ich hoffe ihr könnt mir helfen.
Mein Problem: Ich starte einen Thread, der wiederum einen Windows.Forms.Timer erstellt, dessen Tick Event eine Methode zuweist und den Timer startet.

Hier der Code:



        private System.Windows.Forms.Timer tTmp;
        private Thread thTmp;
        private void button1_Click(object sender, EventArgs e)
        {
            thTmp = new Thread(new ThreadStart(tmpThreadStart));
            thTmp.Start();
        }

        private void tmpThreadStart()
        {
            tTmp = new System.Windows.Forms.Timer();
            tTmp.Interval = 1000;
            tTmp.Tick += ttmp_tick;
            tTmp.Start();
        }

        private void ttmp_tick(object sender, EventArgs e)
        {
            MessageBox.Show("blubb");
        }

Ist nur heißer Beispielcode aber so macht es auch mein Service in dem der Code steckt.
Das Problem ist: die Methode: ttmp_tick wird niemals aufgerufen.

Ich vermute mal, dass es daran liegt, dass der Timer einen eigenen Thread aufmacht oder liege ich da falsch? Nur wie kann ich das beheben?

Grüße und schöne Ostern.

Ben

M
35 Beiträge seit 2009
vor 14 Jahren

Bitte lese dir mal genau den [Hinweis] Wie poste ich richtig?-Thread durch!
Dann würdest du eventuell Google benutzen und nach nichtmal knapp 5 Sekunden auf dieser Seite landen: http://dotnet-snippets.de/dns/c-timer-anlegen-SID111.aspx

Trotzalledem: Frohe Ostern auch dir 😉

Lg Chris

B
bhelbig Themenstarter:in
135 Beiträge seit 2006
vor 14 Jahren

Hi Chris,

danke für den Hinweis. Bin grad dabei mich im MSDN über Thread Timer schlau zu machen.
Kannst du mir verraten, warum beim Zuweisen des Tick Events ich new EvenHandler nutzen muss? Bisher habe ich die Events immer so zugewiesen:


mycontrol.Event += Method1;

und nicht mit:


mycontrol.Event += new EventHandler(Method1);

Grüße

1.044 Beiträge seit 2008
vor 14 Jahren

Hallo bhelbig,

der Thread, der den Timer startest wird sofort wieder beendet. Das macht eigentlich keinen Sinn. Wenn du im Timer bzw. nach dem Starten des Timers z.B. eine MessageBox anzeigest wird in der Zwischenzeit der Timer ausgelöst. Man brauchst also eine Wartezeit nach dem starten des Timers, da sonst der Thread diesen beendet. Wenn du im nach dem starten des Timers ein Thread.Sleep hinzufügst, wird es nicht funktionieren, da es sich im selben Thread befindet.

Hallo Mentor49,

ich glaube, dass du die Problemstellung von bhelbig nicht verstanden hast!

zero_x

P.S.: Ich hoffe, dass ich mit meiner Vermutung richtig liege.

B
bhelbig Themenstarter:in
135 Beiträge seit 2006
vor 14 Jahren

Hi zero_x

logisch. Argh. Danke für den Schups von der Leitung. Der Beispiel code ist nicht wirklich echt. Im echten Code wird keine MessageBox angezeigt, sondern eine XML Datei per URL importiert.
Aber ist ja klar, dass das nicht laufen kann. Da der Timer in einem Windows Service laufen soll ist es denke ich mal eh besser den Thread timer zu verwenden. Hab den zwar noch nie benutzt aber das MSDN Beispiel ist nicht wirklich schwierig.

LG

Ben

M
35 Beiträge seit 2009
vor 14 Jahren

Und auch ich habe wieder was gelernt.
Ich dachte, der Timer würde weiter laufen, auch wenn der Thread in dem der Timer initialisiert und gestartet wurde, beendet ist.

Lg Chris

57 Beiträge seit 2009
vor 14 Jahren

Hallo bhelbig

noch eine kleine Ergänzung.

Eine Eigenheit des 'System.Windows.Forms.Timer' ist, dass er lt. MS nur im Forms-Kontext ausgelöst wird, d. h. nicht in einem separaten Thread, nicht in einem Service und auch nicht in einer Console-EXE.

Am nachfolgenden Beispiel wird das deutlich:



using System;
using System.Timers;
using System.Windows.Forms;

namespace TimerExample
{
    internal class CProgram
    {
        private static void Main (string[] args)
        {
            // System.Windows.Forms.Timer
            
            FormsTimer ();
            
            
            // System.Timers.Timer
            
            SystemTimersTimer ();
            
            
            // block the MainThread
            
            Console.ReadLine ();
        }
        // Main
        
        private static void FormsTimer ()
        {
            // locals
            
            System.Windows.Forms.Timer l_FormsTimer 
                = 
                    new System.Windows.Forms.Timer ();
            
            
            // set the System.Windows.Forms.Timer interval (ms)
            
            l_FormsTimer.Interval = 1000;
            
            
            // register the Tick event
            
            l_FormsTimer
                .Tick 
                    += 
                        (object sender, EventArgs e) 
                            => 
                                MessageBox.Show ("System.Windows.Forms.Timer");
            
            
            // start the System.Windows.Forms.Timer
            
            l_FormsTimer.Start ();
        }
        // FormsTimer
        
        private static void SystemTimersTimer ()
        {
            // locals
            
            System.Timers.Timer l_SystemTimersTimer 
                = 
                    new System.Timers.Timer ();
            
            
            // set the System.Timers.Timer interval (ms)
            
            l_SystemTimersTimer.Interval = 1000;
            
            
            // register the Elapsed event
            
            l_SystemTimersTimer
                .Elapsed
                    += 
                        (object source, ElapsedEventArgs e)
                            => 
                                MessageBox.Show ("System.Timers.Timer");
            
            
            // enable the System.Timers.Timer
            
            l_SystemTimersTimer.Enabled = true;
        }
        // SystemTimersTimer
    }
    // internal class CProgram
}
// namespace TimerExample


'MessageBox.Show ("System.Windows.Forms.Timer");' wird nie aufgerufen. Der 'System.Timers.Timer' funktioniert dagegen so wie er das soll. Du kannst in einem separaten Thread natürlich auch 'System.Threading.Timer' verwenden.

Die aus Deiner Sicht vielleicht etwas seltsamen EventHandler sind anonyme Methoden in Form von lambda expressions.

Gruß
Assri Komla

3.971 Beiträge seit 2006
vor 14 Jahren

Nimm einfach System.Threading.Timer. Ein Gui-Control hat in einem Dienst nichts zu suchen und Thread.Sleep sollte auch immer vermieden werden wo es geht.

Aufpassen beim System.Threading.Timer, immer eine "zugängliche" Variable des Timers haben, sonst räumt der GC den Timer weg und das Callback-Event wird nicht mehr aufgerufen. Am einfachsten umgehst du das Problem mit einem Instanz-Member des Timers.

Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...