Problem mit Exceptions bei einem AsyncCallback
-
Hallo,
wir haben eine Funktion die asynchron ein Datei auf einen Server hochlädt. Da hierbei einiges schiefgehen kann, wollen wir natürlich wissen, ob der Upload geklappt hat. Falls er nämlich nicht geklappt hat, friert der aufrufende Thread ein.
//Code aufs wesentliche gekürzt
Unser erster Test sah so aus:
try { UploadFunktion(); } catch(Exception e) { //hat nicht geklappt }
Dies hat nicht funktioniert, da die asynchrone Exception nicht in diesem Thread geworfen und daher auch nicht aufgefangen werden kann.
Der zweite Versuch sah so aus:
void UploadFunktion() { AsyncCallback callback = new AsyncCallback(FinishUpload); HTTPRequest(callback); } void FinishUpload(IAsyncResult result) { try { using (HttpWebResponse response = (HttpWebResponse)httpWebRequest.EndGetResponse(result)) //hier tritt die Exception auf { //mach was } } catch(Exception e) { MessageBox.Show(e.Message); } }
Hierbei wird die Exception gefangen und ausgegeben. Sobald der Catch-Block verlassen wird, friert allerdings trotzdem der Thread ein, obwohl eigentlich keine offene Exception mehr vorhanden sein dürfte.
Nach etwas googlen (http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,6c02ac47-3336-47f9-b0c9-36025c58cc89.aspx) haben wir das hier probiert:
AsyncCallback Try() { AsyncCallback wrapper = delegate(IAsyncResult iar) { try { cb(iar); } catch (Exception e) { MessageBox.Show(e.Message); } }; return wrapper; } void UploadFunktion() { AsyncCallback callback = new AsyncCallback(FinishUpload); HTTPRequest(Try(callback)); }
Hierbei tritt das gleiche Verhalten auf wie bei dem zweiten Versuch, nur dass die Exception halt eine Ebene weiter hinten gefangen wird, Thread friert trotzdem ein.
Wie kann man das Problem lösen, dass der Thread nicht mehr wegen irgendeiner unbehandelten Exception einfriert, die wir irgendwie nicht fangen können?
greetz KN4CK3R
-
Was meinst du mit "Thread friert ein"? Wenn eine unbehandelte Exception in einem Thread fliegt, dann stürzt das Programm im allgemeinen ab.
Grüssli
-
ist schwer zu beschreiben, was friert ein in dem Fall bedeutet.
Zum Testen läuft der Code momentan direkt in der Main Funktion. Dort friert das Debuggen ein (abgestürzt in dem Fall nehm ich an, nur dass das Visual Studio nicht anzeigt ob er abgestürzt ist oder eingefroren etc).Wenn die Funktion in einem Thread aufgerufen wird, stürzt der aufrufende Thread ab und die Kontrolle hat dann der Thread, der den aufrufenden erzeugt hat (die GUI in dem Fall). Hierbei stürzt nicht das gesamte Programm ab, nur der Thread crasht.
greetz KN4CK3R
-
Also was ich mir vorstellen kann ist, das du zwar die eine Exception fängst, jedoch irgendwo noch eine kommt, dann wird der Thread natürlich abgebrochen. Du musst also erstmal gucken ob es nicht noch eine andere Exception gibt, die den möglichen Absturz erzeugt.
-
und wie kann ich der auf die Schliche kommen? Mehr wie ein try catch außenrumbauen kann ich ja nicht machen oder?
greetz KN4CK3R
-
Naja zu aller erst hätte ich ein Änderungsvorschlag was deinen Upload angeht.
Versuch doch mal folgendesWebClient client = new WebClient(); //UploadData für Daten, UploadFileAsync für ganze Files client.UploadFileCompleted += (s,e) => { //Hier die Behandlung desse was NACH dem Upload geschehen soll }; client.UploadFileAsync("http://www.KN4CK3R.test.de","KN4CK3R.txt");
Damit ersparst du dir das ganze Gefummel mit dem IAsyncResult-Pattern
-
sowas ist schon eingebaut, nur dass er an die Stelle gar nicht mehr kommt
greetz KN4CK3R
-
Hää? An welche Stelle kommt er nicht? Also du hast es so wie ich es gepostet habe. Wo fliegt denn da die Exception?
-
an die Stelle, an der er das ausführen soll was ich ihm bei UploadFileCompleted übergebe, kommt er erst gar nicht
greetz KN4CK3R
-
Naja dann kannst du ja jetzt ein Try-Catch um die Stelle "UploadFileAsync" machen, und dann schaust du was da für eine Exception kommt, und kümmerst dich drum.
-
die Funktion kehrt aber schon zurück bevor in der Asynchronen Funktion ein Fehler auftritt. Ein try catch darum ist wirkungslos, siehe Versuch Nummer 1.
greetz KN4CK3R
-
Und was für eine Exception ist es? Du sollst hier ein Try-Catch drum bauen:
client.UploadFileAsync("http://www.KN4CK3R.test.de","KN4CK3R.txt");