Ich habe einen seltsamen Unterschied zwischen einem Programm, das in VS2005 ausgeführt wird, und dem direkten Ausführen der ausführbaren Datei festgestellt. Im Wesentlichen, wenn eine Ausnahme in einer Methode innerhalb einer Methode ausgelöst wird Application.DoEvents()
Aufruf kann die Ausnahme bei der Ausführung in Visual Studio abgefangen werden. Wenn die kompilierte ausführbare Datei ausgeführt wird, wird die Ausnahme nicht abgefangen und das Programm stürzt ab.
Hier ist ein einfacher Code, der das Problem veranschaulicht. Gehen Sie von einer Standard-Winforms-Vorlage und zwei Schaltflächen und einem Label aus.
Klicken Sie dazu auf die Schaltfläche Start, um den 10-Sekunden-Zähler zu starten. Drücken Sie vor Ablauf der 10 Sekunden auf die Schaltfläche "Abbrechen", und es wird eine Ausnahme in der DoEvents()
. Die Ausnahme sollte abgefangen werden. Dies geschieht nur bei der Ausführung in Visual Studio.
private void StartButton_Click(object sender, EventArgs e) {
DateTime start = DateTime.Now;
try {
while (DateTime.Now - start < new TimeSpan(0, 0, 10)) {
this.StatusLabel.Text = DateTime.Now.ToLongTimeString();
Application.DoEvents();
}
MessageBox.Show("Completed with no interuption.");
} catch (Exception) {
MessageBox.Show("User aborted.");
}
}
private void ButtonAbort_Click(object sender, EventArgs e) {
throw new Exception("aborted");
}
Ich möchte in der Lage sein, diese Ausnahmen abzufangen. Gibt es eine Möglichkeit, dies zu erreichen?
Aktualisierung:
Ich bin bereit, andere Ansätze als die Kopfschmerzen verursachende Wiederholung in Betracht zu ziehen DoEvents()
. Aber ich habe keine gefunden, die besser zu funktionieren scheint. Mein Szenario ist, dass ich eine lange laufende Schleife habe, die einige wissenschaftliche Instrumente steuert und häufig warten muss, bis sich eine Temperatur stabilisiert oder so. Ich möchte meinen Benutzern die Möglichkeit geben, den Prozess abzubrechen, also habe ich eine Abbruchschaltfläche, die einfach eine benutzerdefinierte Ausnahme auslöst, die ich an der Stelle abfangen möchte, an der der Prozess ursprünglich gestartet wurde. Das schien eine perfekte Lösung zu sein. Bis auf die Tatsache, dass es aus irgendeinem Grund nicht funktioniert.
Wenn dies nicht möglich ist, gibt es dann einen besseren Ansatz?
Update 2:
Wenn ich dies als erste Zeile von Main() hinzufüge, funktioniert es als ausführbare Datei, aber nicht in VS, so dass die Situation umgekehrt ist. Das Verrückte daran ist, dass es ein No-op zu sein scheint. Ich kann verstehen, wie dies etwas tut.
Application.ThreadException += delegate(
object sender,
System.Threading.ThreadExceptionEventArgs e
)
{ throw e.Exception; };
Das ist Wahnsinn.