Programm vor Absturz bewahren
Ich möchte vermeiden das sich mein Programm beim Datei Upload aufhängt.
hallo zusm,
ich habe ein Programm welches einen Datei Upload macht erstellt.
Soweit auch kein Problem.
[code]My.Computer.Network.UploadFile(bildpfad.Text, "ftp://.de/data/" & name_endung , "", "***") [/code]
Funktioniert auch super.
Problem liegt jetzt darin, wenn der User schlechtes Internet hat und im Programm rumklickt stürtzt es ab.
Kann man diesen Absturz vermeiden ?
Fals es keine Lösung gibt muss ich halt ein
Me.Hide()
und ein
Me.Show()
einbauen um das Programm vor dem Absturz zu bewahren.
Aber ich denke das geht auch eleganter
Ich bin fün r jedeTipp Dankbar
Greez carp
hallo zusm,
ich habe ein Programm welches einen Datei Upload macht erstellt.
Soweit auch kein Problem.
[code]My.Computer.Network.UploadFile(bildpfad.Text, "ftp://.de/data/" & name_endung , "", "***") [/code]
Funktioniert auch super.
Problem liegt jetzt darin, wenn der User schlechtes Internet hat und im Programm rumklickt stürtzt es ab.
Kann man diesen Absturz vermeiden ?
Fals es keine Lösung gibt muss ich halt ein
Me.Hide()
und ein
Me.Show()
einbauen um das Programm vor dem Absturz zu bewahren.
Aber ich denke das geht auch eleganter
Ich bin fün r jedeTipp Dankbar
Greez carp
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 182042
Url: https://administrator.de/contentid/182042
Ausgedruckt am: 26.11.2024 um 08:11 Uhr
19 Kommentare
Neuester Kommentar
@dan0ne
Jetzt mal so in die Glaskugel geschaut:
Der Upload steht in einer Sub oder Function, ohne Errorhandling.
Hinzu kommt das die Form bedienbar bleibt, ohne das er den Upload in einen Background Thread startet.
Wenn dann der User in der Form Buttons klickt oder andere Events auslöst während der Upload noch läuft knallt es.
Norbert
Jetzt mal so in die Glaskugel geschaut:
Der Upload steht in einer Sub oder Function, ohne Errorhandling.
Hinzu kommt das die Form bedienbar bleibt, ohne das er den Upload in einen Background Thread startet.
Wenn dann der User in der Form Buttons klickt oder andere Events auslöst während der Upload noch läuft knallt es.
Norbert
Was vorstellbar wäre:
- "My.Computer.Network.UploadFile()" ist eine "blocking function"
- Wenn "das Internet schlecht ist" und der user "im Programm rumklickt"
Dann meint Windows "das Program reagiert nicht mehr"
Lösung wäre hier eine non-blocking Function zu benzutzen.
/EDIT: ah, MrTrebron war schneller
- "My.Computer.Network.UploadFile()" ist eine "blocking function"
- Wenn "das Internet schlecht ist" und der user "im Programm rumklickt"
Dann meint Windows "das Program reagiert nicht mehr"
Lösung wäre hier eine non-blocking Function zu benzutzen.
/EDIT: ah, MrTrebron war schneller
Hi !
Warum versuchst Du das nicht über einen modalen Dialog (der solange den Focus hat, bis der Upload abgeschlossen ist) zu regeln? Dann kann der User in der Zeit auch keine Buttons und Menues anklicken. Damit der User sehen kann, dass noch etwas passiert, würde ich evt. dann noch eine Progessbar anzeigen....
mrtux
Warum versuchst Du das nicht über einen modalen Dialog (der solange den Focus hat, bis der Upload abgeschlossen ist) zu regeln? Dann kann der User in der Zeit auch keine Buttons und Menues anklicken. Damit der User sehen kann, dass noch etwas passiert, würde ich evt. dann noch eine Progessbar anzeigen....
mrtux
Es gibt für solche Vorhaben eine Klasse WebClient.
Diese hat eine Methode UploadFileAsync
Du benötigst also keinen BGW
Gruss Mono
Diese hat eine Methode UploadFileAsync
Private WithEvents wc As New Net.WebClient
Sub Upload()
'Userdaten für den FTP Upload.
'Hinweis. DU SOLLTEST KEINE ANMELDEDATEN IM CODE Hinterlegen, auf die KANN JEDER Der das TOOL hat ZUGREIFEN!!
wc.Credentials = New Net.NetworkCredential("user", "pass")
'Upload ASYNC STARTEN (es wrid ein neuer Thread benutzt -> GUI wird nicht blockiert!
wc.UploadFileAsync(New Uri("ftp://ftp.bla.blalala/" & Dateiname), Dateipfad)
End Sub
Private Sub wc_UploadFileCompleted(ByVal sender As Object, ByVal e As System.Net.UploadFileCompletedEventArgs) Handles wc.UploadFileCompleted
'hier ist der Upload fertig
' WICHTIG
' über e.Error bekommst du mit, ob es einen FEHLER gab, und das entsprechend behandeln
End Sub
Private Sub wc_UploadProgressChanged(ByVal sender As Object, ByVal e As System.Net.UploadProgressChangedEventArgs) Handles wc.UploadProgressChanged
'Über e. kommst du auf BytesReceived usw. für deine Progressbar
End Sub
Du benötigst also keinen BGW
Gruss Mono
Hi !
Das ist nicht so einfach, wenn Du keine Klassen (wie der Kollege MonoTone oben schon schreibt) verwendest. Eine Klasse bietet normalerweise dann Ereignisse, die Du auswerten kannst. Ich beziehe mich jetzt aber in meinem rein fiktiven Beispiel grob angenähert an die Syntax von Objekt Pascal (also Delphi oder Lazarus, denn VB ist bei mir schon ein paar Jährchen her).
Da gibt es dann z.B. ein Ereignis OnUpload(Complete: Integer). Der Wert der Variablen Complete könnte Dir dann beispielsweise angeben, wie viele Megabyte schon übertragen wurden. Das kannst Du dann umrechnen und in einer ProgressBar oder einem Label als Prozentwert anzeigen. Das VB Beispiel des Kollegen MonoTone verdeutlicht das ja schon ansatzweise.
Damit das Ereignis immer wieder von neuem ausgelöst werden kann, muss deine Anwendung "immer wieder mal" die Kontrolle an das OS zurückgeben. Unter Delphi mache ich das z.B. mit Application.ProcessMessages. Wenn Du dann einen modalen Dialog verwendest, verliert deine Anwendung, trotz der kurzfristigen Rückgabe an das OS, nicht den Fokus. So kann der User in dieser Zeit normalerweise auch keine anderen Buttons oder Menüs betätigen, bis der Upload-Dialog wieder geschlossen wird und durch die kurzfristige "Rückgabe" an das OS, kann dieses dann auch wieder "CPU Zeit" an andere Anwendungen vergeben und stellt so auch fest, dass deine Anwendung nicht "hängt", um es mal etwas laienhaft auszudrücken.
Den ganzen "Vorgang" kannst Du dann, wie es die Kollegen SlainteMhath und MrTrebron schon erwähnten, über ein Errorhandling (in Object Pascal mach ich das über einen try, except, finally - Block) absichern.
Die obigen Angaben sind nur Beispiele um die Funktionsweise zu verdeutlichen! Eine Klasse WebClient, ein Ereignis OnUpload() und die Variable Complete gibt es unter Delphi natürlich nicht. Wie gesagt, nur um die Sache aus meiner Sicht "so einfach wie möglich" und an einem praktischen Beispiel zu verdeutlichen, denn was nützt einem das perfekte Wissen über eine Programmiersprache, wenn man die Arbeitsweise einer Methode oder die Abläufe hinter einem OS nicht verstanden hat. Erst muss man wissen wie etwas funktioniert (bzw. funktionieren soll), erst dann kann man sich an die programmiertechnische Umsetzung in der Praxis (mittels der "Sprache" seiner Wahl) machen.
mrtux
Zitat von @carp-catcher:
@mrtux klingt gut,...aber wie soll eine Progressbar erstellt werden, die genau anzeigt wann Upload fertig ist ?
@mrtux klingt gut,...aber wie soll eine Progressbar erstellt werden, die genau anzeigt wann Upload fertig ist ?
Das ist nicht so einfach, wenn Du keine Klassen (wie der Kollege MonoTone oben schon schreibt) verwendest. Eine Klasse bietet normalerweise dann Ereignisse, die Du auswerten kannst. Ich beziehe mich jetzt aber in meinem rein fiktiven Beispiel grob angenähert an die Syntax von Objekt Pascal (also Delphi oder Lazarus, denn VB ist bei mir schon ein paar Jährchen her).
Da gibt es dann z.B. ein Ereignis OnUpload(Complete: Integer). Der Wert der Variablen Complete könnte Dir dann beispielsweise angeben, wie viele Megabyte schon übertragen wurden. Das kannst Du dann umrechnen und in einer ProgressBar oder einem Label als Prozentwert anzeigen. Das VB Beispiel des Kollegen MonoTone verdeutlicht das ja schon ansatzweise.
Damit das Ereignis immer wieder von neuem ausgelöst werden kann, muss deine Anwendung "immer wieder mal" die Kontrolle an das OS zurückgeben. Unter Delphi mache ich das z.B. mit Application.ProcessMessages. Wenn Du dann einen modalen Dialog verwendest, verliert deine Anwendung, trotz der kurzfristigen Rückgabe an das OS, nicht den Fokus. So kann der User in dieser Zeit normalerweise auch keine anderen Buttons oder Menüs betätigen, bis der Upload-Dialog wieder geschlossen wird und durch die kurzfristige "Rückgabe" an das OS, kann dieses dann auch wieder "CPU Zeit" an andere Anwendungen vergeben und stellt so auch fest, dass deine Anwendung nicht "hängt", um es mal etwas laienhaft auszudrücken.
Den ganzen "Vorgang" kannst Du dann, wie es die Kollegen SlainteMhath und MrTrebron schon erwähnten, über ein Errorhandling (in Object Pascal mach ich das über einen try, except, finally - Block) absichern.
Die obigen Angaben sind nur Beispiele um die Funktionsweise zu verdeutlichen! Eine Klasse WebClient, ein Ereignis OnUpload() und die Variable Complete gibt es unter Delphi natürlich nicht. Wie gesagt, nur um die Sache aus meiner Sicht "so einfach wie möglich" und an einem praktischen Beispiel zu verdeutlichen, denn was nützt einem das perfekte Wissen über eine Programmiersprache, wenn man die Arbeitsweise einer Methode oder die Abläufe hinter einem OS nicht verstanden hat. Erst muss man wissen wie etwas funktioniert (bzw. funktionieren soll), erst dann kann man sich an die programmiertechnische Umsetzung in der Praxis (mittels der "Sprache" seiner Wahl) machen.
mrtux
Grundsätzlich gebe ich mrtux recht.
Mein Beispiel benötigt allerdings keinen modalen Dialog und auch kein extra Try-catch-
Errorhandling und auch keine Meldung an das Os.
Ich persönlich finde modale Dialoge veraltet...
Man sollte m.E. die GUI immer ansprechbar belassen.
Sollte z.B. der upload sehr langsam vorwärts gehen, will ich den nicht zwingend abbrechen mussen aber
dennoch die GUI bedienen können.
Durch multithreading kann ein thread mit einer Aufgabe parallel und nahezu unabhängig von der Anwendung laufen.
Dadurch kann man die GUI auch problemlos weitet bedienen.
Man muss sich dann nur um die Rückführung der Ergebnisse in die GUI kümmern.
Beim webclient oder beim bgw ist da aber nicht einmal ein cross thread calling Problem vorhanden.
Mein Beispiel benötigt allerdings keinen modalen Dialog und auch kein extra Try-catch-
Errorhandling und auch keine Meldung an das Os.
Ich persönlich finde modale Dialoge veraltet...
Man sollte m.E. die GUI immer ansprechbar belassen.
Sollte z.B. der upload sehr langsam vorwärts gehen, will ich den nicht zwingend abbrechen mussen aber
dennoch die GUI bedienen können.
Durch multithreading kann ein thread mit einer Aufgabe parallel und nahezu unabhängig von der Anwendung laufen.
Dadurch kann man die GUI auch problemlos weitet bedienen.
Man muss sich dann nur um die Rückführung der Ergebnisse in die GUI kümmern.
Beim webclient oder beim bgw ist da aber nicht einmal ein cross thread calling Problem vorhanden.
Hi !
Ja natürlich und wenn Du damit Erfahrung hast, warum nicht? Mein Kommentar von oben ist ja nur ein Vorschlag...
Und dabei muss man aber sorgfältig vorgehen, dabei passieren oftmals Fehler, die dann zu Leaks führen können, daher arbeite ich bei ersten Versionen einer Applikation immer mit modalen Dialogen. Ich bin da eher konservativ und etwas in einen extra Thread "auslagern" kann man ja hinterher auch noch. Manche IDEs bieten dazu sogar schon vorgefertigte Templates, mit denen ich aber auch nicht arbeite...Eben konservativ halt..
mrtux
Zitat von @MonoTone:
Durch multithreading kann ein thread mit einer Aufgabe parallel und nahezu unabhängig von der Anwendung laufen.
Durch multithreading kann ein thread mit einer Aufgabe parallel und nahezu unabhängig von der Anwendung laufen.
Ja natürlich und wenn Du damit Erfahrung hast, warum nicht? Mein Kommentar von oben ist ja nur ein Vorschlag...
Man muss sich dann nur um die Rückführung der Ergebnisse in die GUI kümmern.
Und dabei muss man aber sorgfältig vorgehen, dabei passieren oftmals Fehler, die dann zu Leaks führen können, daher arbeite ich bei ersten Versionen einer Applikation immer mit modalen Dialogen. Ich bin da eher konservativ und etwas in einen extra Thread "auslagern" kann man ja hinterher auch noch. Manche IDEs bieten dazu sogar schon vorgefertigte Templates, mit denen ich aber auch nicht arbeite...Eben konservativ halt..
mrtux