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
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
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
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.
zero_x | <span style="font-size: 10;">my</span><span style="font-size: 10;">CSharp</span><span style="font-size: 10;">.de</span> - gemeinsam mehr erreichen
Für längere Zeit inaktiv.
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
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
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
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...