2016-06-30 2 views
-1

Ich habe einen Bool (b), die nur zweimal in meinem Code (neben seiner Erklärung) erscheint:"finally" nicht ausgeführt wegen Async in "try"?

try 
{ 
    b = true; 
    //code including await SomeAsync(); 
} 
catch { } 
finally { b = false; } 

noch manchmal der try-Block wird gestartet mit btrue sein (- vorb = true) was nie passieren sollte, weil die Deklaration es false verlässt, wie auch die vorherige finally. Irgendwann wird dieser Code in einer Schleife ausgeführt, die in einigen Fällen schnell iteriert und SomeAsync() versucht, zu viel Speicher zu verwenden. Ich nehme an, dass es eine Ausnahme von einem Typ gibt, der finally "brechen" kann. (b ist immer false wie erwartet, wenn es nur eine normale Datenmenge für SomeAsync() zu verarbeiten.)

Ich habe versucht, zu überprüfen, was Visual Studio zeigt mich mit Debug.WriteLine() sowohl nach den try und nach den finally, und auch durch Anhänge zu einer Zeichenkette ein anderes Zeichen an diesen Stellen, aber dann wurde die finally ausgeführt. Also nehme ich an, dass die langsame Verzögerung genug war, um die Ausnahme zu verhindern.

Ist das wirklich möglich? (? Irgendwelche Ideen auf, wie es zu überprüfen oder zu beheben, so dass die schließlich immer läuft)

(schließlich Blöcke kann scheitern - Fälle: Conditions when finally does not execute in a .net try..finally block)

EDIT

Ein guter Punkt war in einem Kommentar und einer Antwort - dass dieser Code mehrere Male während der awaits gleichzeitig ausgeführt werden. Leider gibt es ein anderes Detail (dass diese Antworten mir bewusst gemacht haben, ist relevant) - nach allen Iterationen ist der Zustand b ist true. Das wird nicht durch Nebenläufigkeit erklärt. Ich habe auch einen if (b) return; vor dem try Block hinzugefügt (um zu vermeiden, das Async anzurufen, während das vorherige läuft). Immer noch mit einer trueb verlassen, nachdem alle Iterationen durchgeführt wurden.

+0

Wenn 'b = true' die erste Zeile in Ihrem try-Block ist, wird es immer ausgeführt, da' b = true' nicht fehlschlagen kann. Der "try" -Block wird ausgeführt, bis er fehlschlägt. –

+0

@EliSadoff Es ist 'wahr' _before_ diese Zeile. – ispiro

+0

Aber warum ist das wichtig?Sie können 'b = true' zuweisen, auch wenn' b' bereits 'true' ist. Das wird keinen Fehler verursachen. –

Antwort

2

Dies ist ein ziemlich häufiger Fehler. Der von Ihnen angezeigte Code kann mehrmals gleichzeitig ausgeführt werden. Wenn Sie es zum Beispiel an ein Klickereignis anhängen, kann der Benutzer zehnmal hintereinander auf die Schaltfläche klicken, wodurch zehn Kopien der Funktion fast gleichzeitig ausgeführt werden.

In diesem Beispiel werden sie nicht buchstäblich zur selben Zeit ausgeführt, da sie mit dem UI-Thread verknüpft sind, aber sie können sich mit dem Scheduler überlappen, wenn jedesmal eine await Anweisung angezeigt wird.


Wenn Sie dies im Hintergrund ausgeführt werden (z Thread.Start), dann wird jede Instanz einen eigenen Thread und Sie werden wirklich mehrere Kopien haben zur gleichen Zeit ausgeführt werden.

+0

Guter Punkt. Ihre Antwort, und das gleiche, 2 Minuten früher in [einem Kommentar] (http://stackoverflow.com/questions/38130987/finally-not-executed-bea-cause-of-async-in-try #comment63693896_38130987), ließ mich erkennen dass es ein anderes relevantes Detail gab (jetzt in die Frage bearbeitet) - dass "b" nach allen Iterationen "wahr" bleibt. Aber danke! – ispiro