Laden...

System.Threading.Timer schmiert ab

Erstellt von inek vor 13 Jahren Letzter Beitrag vor 13 Jahren 5.228 Views
inek Themenstarter:in
182 Beiträge seit 2007
vor 13 Jahren
System.Threading.Timer schmiert ab

Hallo zusammen. Ich nutze nen Threading.Timer um in einer textbox die aktuelle Uhrzeit an zu zeigen... das mache ich wie folgt:


System.Threading.TimerCallback clockTimerDelegate = new System.Threading.TimerCallback(this.ClockTimerCallback);
this.m_Clock.Text = DateTime.Now.ToString("HH:mm:ss");
this.m_ClockTimer = new System.Threading.Timer(clockTimerDelegate, null, 1000, 1000);

im callback setz ich dann nur den text der Textbox.
alles funktioniert ca 6-7 sekunden.. dann geht alles aus und die form wird geschlossen.
was mach ich falsch ?

6.911 Beiträge seit 2009
vor 13 Jahren

Hallo,

höchstwahrscheinlich [FAQ] Controls von Thread aktualisieren lassen (Control.Invoke/Dispatcher.Invoke) da der System.Threading.Timer eben in einem anderen Thread als der UI-Thread läuft.

Warum verwendest du nicht den Winforms-Timer? Der ist im gleichen Thread-Kontext.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

1.044 Beiträge seit 2008
vor 13 Jahren

Hallo inek,

warum so kompliziert? Verwende einfach die Timer-Klasse und fertig. Beachte, dass es mehrere Timer im .NET Framework gibt. Du musst für deine Zwecke den WinForms-Timer verwenden.

zero_x

3.971 Beiträge seit 2006
vor 13 Jahren

solltest auch darauf achten, dass du dir immer die Timer-Instanz merkst. Tust du das nicht, räumt der GC dir den Timer weg und das Ticken hört dann auf.

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

1.044 Beiträge seit 2008
vor 13 Jahren

Hallo kleines_eichhoernchen,

vorsicht, der GC kann die Referenz erst wegräumen, wenn die Klasse auch null ist und keine weiteren Referenzen auf diese verweisen! Um ein wenig Werbung für meinen Blog zu machen: Ist null immer null?.

zero_x

3.170 Beiträge seit 2006
vor 13 Jahren

Hallo,

vorsicht, der GC kann die Referenz erst wegräumen, wenn die Klasse auch null ist und keine weiteren Referenzen auf diese verweisen!

Das kann man so nicht stehen lassen, denn:

  • eine Klasse kann nicht null sein, höchstens eine Variable/Feld.
  • der GC kann sehr wohl Objekte wegräumen, wenn noch eine Referenz besteht, wenn er feststellt, daß diese im weiteren Programm nicht mehr benutzt werden kann. Ein kurzes Beispiel:
void MyFunction()
{
  MyClass myClass = new MyClass();
  
  myClass.DoSometing();
  myClass.DoSomethigElse();

  // An dieser Stelle könnte der GC das Objekt bereits abräumen,
  // wenn es (als lokale Variable) in der Funktion nicht mehr verwendet wird,
  // auch wenn sie NICHT genullt wird

  // --- Code der myClass nicht mehr benutzt ---
}

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

1.044 Beiträge seit 2008
vor 13 Jahren

Hallo MarsStein,

eine Klasse kann nicht null sein, das stimmt. Damit meine ich aber die Instanz, also das Objekt. Meine Aussage war aber auf einen anderen Zusammenhang bezogen. Ich meinte das nicht so wie in deinem Beispiel. In der Regel setzt man Timer so ein, dass diese nicht in einer Methode ihre Lebenszeit verlieren.

zero_x

3.170 Beiträge seit 2006
vor 13 Jahren

Hallo zero_x,

mein Beispiel ist auch nicht auf den Fall einer lokalen Variablen beschränkt. Der GC darf im allgemeinen alle Objekte abräumen, von denen er feststellt, daß sie im nachfolgenden Programmverlauf nicht mehr erreicht werden - ganz unabhängig davon wie es dazu kommt.
So könnte z.B. im Timer-Kontext ein Objekt, das den Timer nutzt, abgeräumt werden, nachdem z.B. eine entsprechende Instanzvariable überschrieben wird. Dann könnte auch der Timer flöten gehen.

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

6.911 Beiträge seit 2009
vor 13 Jahren

Hallo,

Der GC darf im allgemeinen alle Objekte abräumen, von denen er feststellt, daß sie im nachfolgenden Programmverlauf nicht mehr erreicht werden

Stimmt. Aber im obigen Beispiel wird die Instanz von MyClass welche in myClass gehalten wird nicht abgeräumt da bis zum Ende der Methode die Referenz eben gehalten wird. Würde eine neue Instanz zugewiesen so könnte die ursprüngliche abgeräumt werden.
Der GC führt keine Flow-Analyse durch mit welcher das was im Bsp. gezeigt wird ermöglicht würde dafür unterstützt der JITer aber den GC mit den nötigen Informationen (aber nur im Release-Build).

Edit: Falsches gestrichen und bei der Flow-Analyse den JIT ergänzt.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

5.742 Beiträge seit 2007
vor 13 Jahren

Aber im obigen Beispiel wird die Instanz von MyClass welche in myClass gehalten wird nicht abgeräumt da bis zum Ende der Methode die Referenz eben gehalten wird. Würde eine neue Instanz zugewiesen so könnte die ursprüngliche abgeräumt werden.

Falsch!

Ausführen und wundern (aber als Release-Build) 😉


Foo foo = new Foo();
WeakReference reference = new WeakReference(foo);

foo.Bar();

Console.ReadLine();
GC.Collect();

Console.WriteLine(reference.IsAlive);
Console.ReadKey();

Ausgabe "false".

[EDIT]Hier auch ein Link dazu: When does an object become available for garbage collection?[/EDIT]

3.170 Beiträge seit 2006
vor 13 Jahren

Hallo Gü,

Aber im obigen Beispiel wird die Instanz von MyClass welche in myClass gehalten wird nicht abgeräumt da bis zum Ende der Methode die Referenz eben gehalten wird.

Bist Du Dir da sicher? Ich war bisher immer anderer Ansicht, dafür sprechen auch
[gelöst] Dienst mit integriertem Timer läuft nur sporadisch ff
MemoryLeaks / nicht abgehängte Events

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

6.911 Beiträge seit 2009
vor 13 Jahren

Hallo,

Bist Du Dir da sicher?

Als ich das schrieb schon noch jetzt bin ich mir sicher dass es falsch war - da hab ich wohl die falschen MS-Quellen gelesen (wie zB die Sprach-Spezifikation). Ich wusste nicht dass der JITer hier dem GC hiflt.

Aber die Aussage war und ist falsch. Habs oben auch korrigiert.

D.h. auch dass das vom MS empfohlene explizite null-Setzen wie in den Performance-Patterns vorgeschlagen ist icht nötig - cool da hab ich was gelernt 😉

Danke für die Klarstellung!

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"