2013-11-23 13 views
6

Ich habe eine C# .NET Konsolenanwendung, die eine E-Mail mit SmtpClient sendet.Der Prozess oder Thread hat sich seit dem letzten Schritt geändert (Visual Studio)

Ich bin erfährt das folgende Verhalten in dem folgenden Code gezeigt:

  1. einen Haltepunkt irgendwo Stellen über der Linie 35
  2. den Haltepunkt Hit, bis zum 30. Linie Schritt, 32, usw.
  3. Vor trifft es Zeile 35, springt er wieder auf 28 wieder an der Leitung
  4. irgend~~POS=TRUNC bekomme ich die „der Prozess oder Thread seit dem letzten Schritt geändert hat“ Nachricht
  5. Das Springen scheint sich um zufällige

The process or thread has changed since last step screen shot

Warum kommt der Bruchstelle Sprung um?

Was bedeutet diese Nachricht?

Ist irgendetwas mit meinem Code falsch?

(Here's another similar question on Stackoverflow. Wahrscheinlich ist die gleiche Sache, aber es ist ASP.NET)


Per Hans Passants Tipp folgt.

Diese Version noch erlaubt Race-Bedingung: Toggle Timer.AutoReset Eigenschaft in Ereignishandler meine Timers Neueintritt zu vermeiden, während Code ausgeführt wird.

private void OnTimerElapsed(object source, ElapsedEventArgs e) 
{ 
    timer.AutoReset = false; // prevent another Elapsed event 
    MyClass.SendMail(smtpServer, account, password); // do stuff 
    timer.AutoReset = true; // allow another Elapsed event 
} 

Endfassung: Initialisieren Sie den Timer mit AutoReset bereits auf false gesetzt, dann rufen Sie Timer.Start() wieder am Ende Ihrer verstrichene Ereignishandler.

Antwort

7

Sie haben mehr als einen Thread, der die gleiche Methode ausführt und alle denselben Breakpoint haben. Wenn Sie fortfahren, kann der Debugger nicht mehr genau erraten, in welchem ​​Thread er den Status anzeigen soll. Sie erhalten also eine Warnung, dass Sie jetzt den Zustand eines anderen Threads betrachten. Die lokalen Variablenwerte können unterschiedlich sein. Wie ist der Ausführungsort natürlich, der Grund, der die Hervorhebung ändert.

Dies kann das Debugging natürlich erschweren. Sie möchten dies vermeiden, wenn Sie immer noch Bugs aus dem Code bekommen, starten Sie nur einen Thread. Darüber hinaus ist eine temporäre Problemumgehung, Debug + Windows + Threads zu verwenden, klicken Sie mit der rechten Maustaste auf einen der Threads, und wählen Sie Freeze aus. Vergiss nicht, wieder aufzutauen.

+0

Diese Methode ist "statisch", aber ich korrigiere in der Annahme, dass das gleiche passieren würde, auch wenn es nicht war, und ich musste jedes Mal eine neue Instanz des Objekts erstellen, wenn ich eine E-Mail senden wollte?Auch, bin ich richtig in der Annahme, der Grund, warum ich mehrere Threads Ausführung des gleichen Codes habe, ist, weil ich ein Ereignis alle 1 Sekunde feuern muss, und jedes Mal, wenn ich F10 * langsam * treffe, wird die Methode von diesem Ereignis erneut aufgerufen? – JohnB

+1

Ob es statisch ist oder nicht, ist nicht relevant. Einen Timer zu verwenden, um diese Methode aufzurufen, ist ein sehr guter Weg, um in diese Art von Schwierigkeiten zu kommen. Wenn das Senden einer E-Mail länger als 1 Sekunde dauert, erhalten Sie * einen anderen Thread, der vom Timer gestartet wird, um die Methode auszuführen. Sehr ungesund. Und unausweichlich, wenn Sie die Methode einzeln durchlaufen, dauert das natürlich immer mehr als eine Sekunde. Denken Sie über die Weisheit nach, * achtzigtausend * E-Mails pro Tag zu senden. Vermeiden Sie diese Neuigkeit, indem Sie die Eigenschaft AutoReset des Timers auf false setzen. –

+0

Danke für den Tipp! Habe ich Ihren Vorschlag richtig umgesetzt? (Siehe Update zu meiner Frage oben.) * Btw, das 1-Sekunden-Timer-Intervall war nur für Testzwecke. In der realen Welt ist mein Timer viel seltener. * – JohnB

Verwandte Themen