Retry on download failure

0 votes
asked Mar 30, 2013 by Simbiat (120 points)
edited Apr 2, 2013


I am bit of a newbie with coding in general and rebex in particular, so, can you help me out a bit? What I am trying to do is retry download action, but for some reason it crashes application. When debugging it suggests using "Invoke" in different parts NOT related to actual download, so, using it does not not help, so I'm guessing I'm doing something wrong.

In short, I initiate BeginDownload like this:

Dim result As IAsyncResult = FTP.BeginDownload(commonfolder, steamlocation & "\steamapps\common", TraversalMode.Recursive, TransferMethod.Copy, ActionOnExistingFiles.OverwriteDifferentSize, New AsyncCallback(AddressOf FinishCommonDownload), Nothing)

FinishCommonDownload in turn downloads some more files to a different folder, and calls another download similar to it. I the end FinishLoad is called:

Private Sub FinishLoad(ByVal result2 As IAsyncResult)
    Dim dfail As Integer
    Catch ex As Exception
        dfail = dfail + 1
    End Try

    If dfail <> 1 Then
        NotifyIcon.BalloonTipIcon = ToolTipIcon.Info
        NotifyIcon.BalloonTipTitle = "Download completed"
        NotifyIcon.BalloonTipText = "Your download of " & gameloaded & " is now completed" & vbNewLine & "Enjoy :)"
        MsgBox("Your download of " & gameloaded & " has failed" & vbNewLine & "Please, retry")
    End If

    If (Me.InvokeRequired) Then
        Me.Invoke(New Action(Of Boolean)(AddressOf SetState), New Object() {False})
    End If
End Sub

I tried calling my download function from the "Catch", but when it comes back to the "Dim result..." part it crashes the app. And does not seem like debugger catches this exact exception.

I'm getting a hunch, that this is a wrong move :D I tried to understand, how I should use "Retry" method, which Rebex should have, but, as I said, I am a noob and do not get how I should do it. Can someone, please, assist? BTW, even though it says FTP it's actually SFTP ;)

Applies to: Rebex SFTP

1 Answer

0 votes
answered Apr 1, 2013 by Lukas Pokorny (97,590 points)
edited Apr 2, 2013

I guess calling NotifyIcon.something from the FinishLoad async callback might be an issue - if Me.InvokeRequired is True, you are not supposed to be setting properties or accessing most methods of controls created from the application's main thread, and that might apply to notify icon as well. My advice would be to call Me.Invoke (or perhaps rather Me.BeginInvoke) to transfer control to a method running in applications main thread as soon as possible. You can actually do that even before calling EndDownload - just pass the IAsyncResult object using Invoke if needed, and call EndDownload (and do any additional actions) in the invoked method. That way, you should no longer have to deal with those nasty crashes.

commented Apr 1, 2013 by Simbiat (120 points)
edited Apr 1, 2013

NotifyIcon is called only in case of successful download, so it's not the issue here. I am having the issue in case of failure, when I want to retry the download action. Current code shows:

MessageBox.Show(ex.ToString()) dfail = dfail + 1

And I tried doing it like this:

MessageBox.Show(ex.ToString()) dfail = dfail + 1 Download()

And this is what gives me the crash. What I want is instead of Download() use something else, native to Rebex, to retry the failed action in the initial BeginDownload

commented Apr 2, 2013 by Lukas Pokorny (97,590 points)
edited Apr 2, 2013

It's impossible to tell what might be wrong without access to the actual Download method call. Try calling the Download method using Me.Invoke, that should get rid of the crash and you can retry the failed action (call BeginDownload to restart) in the Download method.