Our Products:   CompleteFTP  edtFTPnet/Free  edtFTPnet/PRO  edtFTPj/Free  edtFTPj/PRO
0 votes
5.6k views
in .NET FTP by (1.9k points)
Hello,

I am trying to write an application that uploads multiple files to ftp servers. I chose to use Asynch methods in FTPExpress. Now when I look at the example viewe snippet I am a bit confused. First here is what I am using:


Dim ftpConn As New EnterpriseDT.Net.Ftp.ExFTPConnection
  With ftpConn
            .ServerAddress = "192.168.5.33"
            .UserName = "admin"
            .Password = "password"
            .ServerDirectory = "/troot/"
        End With

ftpConn.BeginConnect(New AsyncCallback(AddressOf OnConnect), ftpConn)
ftpConn.BeginUploadFile(dg.FileName, IO.Path.GetFileName(dg.FileName), New AsyncCallback([b]AddressOf OnUpload[/b]), ftpConn)
ftpConn.BeginClose(New AsyncCallback(AddressOf OnClose), ftpConn)

  
  Private Sub OnConnect(ByVal ar As IAsyncResult)
        Dim c As ExFTPConnection = CType(ar.AsyncState, ExFTPConnection)
        c.EndConnect(ar)
        Console.WriteLine("Connect completed")
    End Sub 'OnConnect
  
  Private Sub OnUpload(ByVal ar As IAsyncResult)
        Dim c As ExFTPConnection = CType(ar.AsyncState, ExFTPConnection)
        c.EndUploadFile(ar)
        PrintLine("Upload completed"+ " " + c.)
    End Sub 'OnUpload
  
  Private Sub OnClose(ByVal ar As IAsyncResult)
        Dim c As ExFTPConnection = CType(ar.AsyncState, ExFTPConnection)
        c.EndClose(ar)
        Console.WriteLine("Close completed.  Signalling main thread")
    End Sub


Now my question is:

1) Why do you have to call c.endupload and c.end close for each command?

2) What is the difference between using an Asynch Callbackresult in each command like above and using an event handler like (AddHandler ftpConn.Uploaded, AddressOf OnUpload) ?

3) If I use the above technique how can I track statistics like file names, file upload success, file upload failure, file upload error? I used to manage that by event handlers.


thanks

8 Answers

0 votes
by (161k points)
Our asynchronous methods are based on the Microsoft model - it is worth reading up on.

1. You call the end methods to complete the asynchronous call. That's when exceptions are thrown.
2. You need to use AsyncCallback - that's how the async model works.
3. You will know when you call the End method if it succeeded or failed. You can also pass in a state object to the Begin method that is available in the callback.
0 votes
by (420 points)
Our asynchronous methods are based on the Microsoft model - it is worth reading up on.

1. You call the end methods to complete the asynchronous call. That's when exceptions are thrown.
2. You need to use AsyncCallback - that's how the async model works.
3. You will know when you call the End method if it succeeded or failed. You can also pass in a state object to the Begin method that is available in the callback.


Just to expand on this answer a bit:

Go to www.google.com and type 'msdn multithreading' without the quotes. Check out the Microsoft Developer Network articles on that. Asynchronous operations are performed on separate threads; you would really only need to do something like this for multiple uploads if you either wanted the user to be able to keep working in the application while uploading (this can cause problems if you don't have a firm grasp on multithreaded programming) or if you wanted to provide some kind of User Interface progress report (like a Windows.Forms.Form with a Progressbar control) which needed to update itself while the asynchronous operation is processing.

You should really do a bit of experimentation with multithreaded programming, using Delegates to pass data and perform actions from one thread to the next, and implementing Thread Locks in code (and a lot of study on the results) before you try to develop using Asynchronous methods.

Event Handler routines as defined by AddHandler work for Synchronous Operations (on a single thread), so for example: If you want to use standard Event Handlers instead of screwing around with Asynchronous methods and callback delegates (but you also want your users to be able to keep working in the application as the operations are performed) then you should be starting a separate thread and creating the object you're working with on that thread - then in order to customize your event handlers you would create your own class that imports the EnterpriseDT namespace and inherits the FTPConnection control, and the first operation performed on the separate thread would be creating a new object of that class.
0 votes
by (1.9k points)
Hi,

Event Handler routines as defined by AddHandler work for Synchronous Operations (on a single thread), so for example: If you want to use standard Event Handlers instead of screwing around with Asynchronous methods and callback delegates (but you also want your users to be able to keep working in the application as the operations are performed) then you should be starting a separate thread and creating the object you're working with on that thread - then in order to customize your event handlers you would create your own class that imports the EnterpriseDT namespace and inherits the FTPConnection control, and the first operation performed on the separate thread would be creating a new object of that class.


Can you give a simple quick example of that. Just a glimpse of what you mean.

Thanks a lot
0 votes
by (1.9k points)
Hello Bruce,

Thanks for your answer. As far as I understand, AddHandler is for Synchronous method. Now, how can I use an event like BytesTransferred. I wish to use it you know to calculate the speed of all the uploads.

Thanks
0 votes
by (420 points)
This example is written in VB.NET with Visual Studio 2008, using DotNET Framework 3.5. It's built on a "Windows Forms Application" with a single Form (Form1) and the Reference to the EnterpriseDT namespace DLL is added explicitly. I'm using EnterpriseDT NET Free version.

You don't really need all the Imports here, but if you start customizing other controls in the namespace it's nice to have the whole thing laid out right from the start.


Imports EnterpriseDT
Imports EnterpriseDT.Net
Imports EnterpriseDT.Util.Debug
Imports EnterpriseDT.Net.Ftp

Public Class Custom_FTPConnection_Class
Inherits FTPConnection

Private TimeInTransfer As TimeSpan
Private TransferTimer As DateTime
Private TransferAmount As Integer = 0

Private Sub Uploading_EventHandler() Handles Me.Uploading
TransferTimer = Date.Now
TransferAmount = 0
End Sub

Private Sub BytesTransferred_EventHandler() Handles Me.BytesTransferred
TransferAmount = TransferAmount + TransferBufferSize
TimeInTransfer = Date.Now.Subtract(TransferTimer)


MsgBox(TransferAmount & " bytes transferred in " & TimeInTransfer.Milliseconds & " milliseconds at a calculated speed of " & TransferAmount / TimeInTransfer.Milliseconds & " bpms.")
End Sub

End Class

The above is your custom class with event handling for BytesTransferred. It demonstrates how to track bytes uploaded using the BytesTransferred Event and the TransferBufferSize, and the simple maths involved in calculating the transfer speed based on that data.

Below is the code for the Form itself.


Public Class Form1

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim CustomFTPThread As New System.Threading.Thread(AddressOf Threaded_CustomFTP)
CustomFTPThread.Start()
End Sub

Private Sub Threaded_CustomFTP()
Dim MyFTPDemo As New Custom_FTPConnection_Class
MyFTPDemo.ServerAddress = 'You need to supply your own ServerAddress String
MyFTPDemo.ServerPort = 'You need to supply your own Port Integer
MyFTPDemo.UserName = 'You need to supply your own UserName String
MyFTPDemo.Password = 'You need to supply your own Password String
MyFTPDemo.Connect()

Dim strOutput As System.IO.StreamWriter = My.Computer.FileSystem.OpenTextFileWriter("C:\Test.txt", 0)
strOutput.Write("HELLO WORLD!")
strOutput.Close()

MyFTPDemo.UploadFile("C:\Test.txt", "Test.txt")

MyFTPDemo.Dispose()
End Sub
End Class

What actually happens in this Form Code is that when you first start the Application, it creates and fires a separate thread. The separate thread first creates a new object of our custom Class (the EnterpriseDT inherited FTPConnection with Bytes Transferred event handling), then connects, creates a new Text File on your C:\ drive, and then uploads that file to the connected FTP Server.

Make sure you replace my comments in the above code with valid FTP Server data before you run the demo.

Hope this helps.
0 votes
by (1.9k points)
This seems like a nice and organized way than what i was doing. However, when I attempt to do it using VS 2005, I get the 'not having the same signature error' in the IDE interpreter, i.e. for e.g.

Error   1   Method 'Private Sub Uploading_EventHandler()' cannot handle Event 'Public Event Uploading(sender As Object, e As EnterpriseDT.Net.Ftp.FTPFileTransferEventArgs)' because they do not have the same signature.   C:\Documents and Settings\WZ\Local Settings\Application Data\Temporary Projects\CustomFTPclass\clsFTPConnections.vb   15   53   CustomFTPclass


I usually see this when the event arguments of the delegate and the event handler are not the same. I'd fix that by declaring any parameters in the method to be of type object instead. Any ideas?
0 votes
by (420 points)
I had a sense that I should include those event arguments when I was writing, but it worked for me (without them) in Debug Mode with VS2008.

Change the sub declarations as follows:

Private Sub Uploading_EventHandler(ByVal sender As System.Object, ByVal e As EnterpriseDT.Net.Ftp.FTPFileTransferEventArgs) Handles Me.Uploading


Private Sub BytesTransferred_EventHandler(ByVal sender As System.Object, ByVal e As EnterpriseDT.Net.Ftp.BytesTransferredEventArgs) Handles Me.BytesTransferred


Also, and I should have considered this before posting the example, if you use e.ByteCount instead of TransferBufferSize you'll get a more accurate return of the number of bytes transferred.

IE: In the BytesTransferred_Eventhandler
TransferAmount = TransferAmount + e.ByteCount

instead of
TransferAmount = TransferAmount + TransferBufferSize
0 votes
by (1.9k points)
That did it. I am experimenting with e.bytecount now as well. My challenge now is getting an accurate speed calc. I know how to do it. I am just trying to manage updating the GUI without locking up the main thread. As for Async methods, I believe I will resort to using your recommendation for a custom class.

Thanks.

Categories

...