Ho una domanda di console C# .NET che invia un'email utilizzando SmtpClient
.Il processo o il thread è stato modificato dall'ultimo passaggio (Visual Studio)
Sono sperimenta il seguente comportamento nel codice riportato di seguito:
- Impostare un punto di interruzione da qualche parte sopra la linea 35
- Hit il punto di rottura, passo attraverso la linea 30, 32, ecc
- prima che colpisce la linea 35, salta indietro fino alla linea 28 di nuovo
- ad un certo punto, ho la "il processo o il thread è cambiato da ultimo passo" messaggio
- Il salto intorno sembra casuale
Perché il mio punto di rottura salto in giro?
Che cosa significa questo messaggio?
C'è qualcosa che non va nel mio codice?
(Here's another similar question on Stackoverflow. Probabilmente la stessa cosa, ma è ASP.NET) punta
Per Hans passants di seguito.
Questa versione ancora permessi race condition: Toggle Timer.AutoReset
proprietà in gestore di eventi di mio timer per evitare la re-entrancy mentre il codice è in esecuzione.
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
}
versione finale: Inizializzare il timer con AutoReset
già impostato su false, quindi chiamare Timer.Start()
di nuovo alla fine del vostro gestore di eventi trascorso.
public void Start()
{
timer = new Timer(checkInterval);
timer.Elapsed += new ElapsedEventHandler(OnTimerElapsed);
timer.AutoReset = false; // prevent race condition
timer.Start();
}
private void OnTimerElapsed(object source, ElapsedEventArgs e)
{
bool exceptionIsNasty = false;
try {
MyClass.SendMail(smtpServer, account, password); // do stuff
}
catch (Exception ex) {
// Log exception, set exceptionIsNasty to true if the mailing should be stopped
//...
}
finally {
if (!exceptionIsNasty) timer.Start(); // allow another Elapsed event
}
}
Questo metodo è 'statico', ma ho ragione nel ritenere che la stessa cosa sarebbe accaduta anche se non lo fosse, e ho dovuto creare una nuova istanza dell'oggetto ogni volta che volevo inviare una e-mail?Inoltre, ho ragione a supporre che il motivo per cui ho più thread che eseguono lo stesso codice è perché ho un evento che si attiva ogni 1 secondo, e ogni volta che * lentamente * prendo F10, il metodo viene chiamato di nuovo da quell'evento? – JohnB
Se è statico o meno non è rilevante. Usare un timer per chiamare questo metodo è un ottimo modo per entrare in questo tipo di problemi. Se l'invio di un messaggio di posta elettronica richiede più di 1 secondo, verrà generato un * altro * thread avviato dal timer per eseguire il metodo. Molto malsano. E inevitabile quando monti il metodo, che ovviamente richiede sempre più di un secondo. Prendi in considerazione la saggezza di mandare * ottantamila * email al giorno. Evitare questa riaccranatura impostando la proprietà AutoReset del timer su false. –
Grazie per il suggerimento! Ho implementato correttamente il tuo suggerimento? (Vedere aggiornamento alla mia domanda sopra.) * A proposito, l'intervallo del timer di 1 secondo era solo a scopo di test. Nel mondo reale, il mio timer è molto meno frequente. * – JohnB