Our Products:   CompleteFTP  edtFTPnet/Free  edtFTPnet/PRO  edtFTPj/Free  edtFTPj/PRO
0 votes
7.4k views
in .NET FTP by (440 points)
I'm using the edtftp control in a small FTP application made in VB 2005. I've been working on it for a couple of weeks and everything was ok. The last few days I have been tweaking the GUI, and I've added an option to start minimized. The weird thing is, when I start the program minimized and it starts to transfer the file specified in the commandline, I get an error. When I run it with Me.Windowstate = FormWindowState.Normal the transfer works fine. When I start the program normally, and I minimize it between the FTP connect and transfer, it also gives the error. If I minimize the form AFTER the transfer has started, it works fine

This is the error I'm getting
Exception has been thrown by the target of an invocation.

            If FtpC.IsConnected = True Then
                Try
                    StatusLabel.Text = "Uploading file: " & DestinationFile
                    FtpC.UploadFile(s, DestinationFile)
                Catch ex As System.Exception
                    Console.WriteLine("Error during transfer" & vbCrLf & ex.Message)
                    MessageBox.Show("Error during transfer" & vbCrLf & ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
                    Exiting = True
                    Application.Exit()
                    End
                End Try
            End If

So, the above code runs fine when the form is in its normal state, but it throws an exception when minimized.

14 Answers

0 votes
by (162k points)
It's a bug in your code. It is falling over here:

Public Sub FtpC_BytesTransferred(ByVal sender As Object, ByVal e As EnterpriseDT.Net.Ftp.BytesTransferredEventArgs) Handles FtpC.BytesTransferred
ProgressBar1.Value = e.ByteCount
End Sub

This is falling over because ProgressBar1.Value is by default between 0 and 100.

You don't call ProgressBar1.Maximum = FileSize in Form1_Load until *after* the transfer is attempted for Minimized = 1.

You obviously need to set this before doing the transfer so the progress bar is set up correctly.
0 votes
by (440 points)
Doh! That was just pretty stupid of me. But that wasn't the problem. I fixed that, and then noticed I wasn't running the transfer on a separate thread (as I do in my real program). I've mailed another version of this test program which now accurately reproduces the problem. So it's a combination of the threading, plus the form hiding which causes the exception. If I remove the threading code the transfer works fine hidden

I've mailed you the source of the Form1.vb file. Open the project, then view the source of Form1.vb and the replace it with the content of the file I sent. That should do the trick
0 votes
by (51.6k points)
Hi Wout

I've run your program and (after a little modification) got an error during transfer. I was quickly able to identify the problem by enabling "Break on exception" within VS.NET. To use this feature, select "Exceptions..." from the "Debug" menu, and then check the checkbox in the "Thrown" column on the "Common Language Runtime Exceptions" row. When you run it now you should see it stopping inside the BytesTransferred event-handler when you try to update the progress bar.

The exception that is thrown is "Cross-thread operation not valid: Control 'ProgressBar1' accessed from a thread other than the thread it was created on.". You could also have found this error by looking more closely at the exception that you caught in Start_Transfer(). It is a TargetInvocationException, so you need to look at the InnerException member to see the actual exception that was thrown.

So what's the problem? The problem is that you are trying to update a control on the form from a thread other than the thread that was used to create the control. This is not allowed in Windows Forms, which is quite annoying. Fortunately it's not hard to work around the problem. You need to use the Control.BeginInvoke(Delegate method, params Object[]) method.

So, instead of your current FtpC_BytesTransferred method, which looks like this:
Public Sub FtpC_BytesTransferred(ByVal sender As Object, ByVal e As EnterpriseDT.Net.Ftp.BytesTransferredEventArgs) Handles FtpC.BytesTransferred
    ProgressBar1.Value = e.ByteCount
End Sub

you need to do this:
Delegate Sub UpdateProgressBarDelegate(ByVal byteCount As Long)

Public Sub FtpC_BytesTransferred(ByVal sender As Object, ByVal e As EnterpriseDT.Net.Ftp.BytesTransferredEventArgs) Handles FtpC.BytesTransferred
    Dim arguments(0) As Object
    arguments(0) = e.ByteCount
    ProgressBar1.Invoke(New UpdateProgressBarDelegate(AddressOf UpdateProgressBar), arguments)
End Sub

Private Sub UpdateProgressBar(ByVal ByteCount As Long)
    ProgressBar1.Value = ByteCount
End Sub


Please let me know if that solves the problem.

- Hans (EDT)
0 votes
by (440 points)
Hi Hans,

Thanks for the great deal of support, seeing that this turned out to be a programming error on my side instead of en error caused by edtftp. Your suggestion indeed fixed the problem! I'm pretty new to VB.NET and this is the first time I'm working with multiple threads. It's obvious I still have a lot to learn.
Once again, thanks a lot!

Categories

...