Our Products:   CompleteFTP  edtFTPnet/Free  edtFTPnet/PRO  edtFTPj/Free  edtFTPj/PRO
0 votes
2.3k views
in .NET FTP by (780 points)
What is the cleanest and most reliable way to cancel a connection attempt using the SecureFTPConnection that is taking a long time? I have tried calling Connect on a separate thread, and then calling Close(True) from the main thread if the user hits my Cancel button. Sometimes this works if the server is up and there are just problems negotiating with it. But if the server is not even accessible, it will wait the full timeout value before the Connect method finally returns and my worker thread finishes. I have tried the asynchronous BeginConnect and then calling AbortAsynchronous, but can't seem to get that working either. Is AbortAsynchronous only for transfers? What is the generally accepted way to cleanly stop a connection and have all underlying sockets immediately destroyed and disposed of?

5 Answers

0 votes
by (161k points)
AbortAsynchronous is for canceling transfers. Have you tried using BeginConnect and then Close(True) if cancel is chosen?
0 votes
by (780 points)
Yes, and I get the same result with BeginConnect. See the sample code:

' StopSignal is a ManualResetEvent parameter that I set when the user clicks my Cancel button.

myFTP.Timeout = Timeout
ar = myFTP.BeginConnect(Nothing, Nothing)
Dim SignalHandles(1) As WaitHandle
SignalHandles(0) = ar.AsyncWaitHandle
SignalHandles(1) = StopSignal
WaitIndex = WaitHandle.WaitAny(SignalHandles, Timeout + 1000)

If (WaitIndex = 0) Then
    myFTP.EndConnect(ar)

    If (myFTP.IsConnected) Then
         Result = True
    End If
Else
    myFTP.Close(True)
End If


If the server I am trying to connect to is not even on the network, the Close(True) call will return immediately, but subsequent calls like any of the following lines (by themselves)

myFTP.Close()
RemoveHandler myFTP.CommandSent, AddressOf Me.LogFTPCommand
myFTP.Dispose()


will block until the original timeout used to try the connection expires. If I were to set a timeout of 2 minutes, the code blocks on any one of these calls for that 2 minutes even though I have canceled the connection with Close(True). I have also seen the same result while using an actual callback function.

My program actually tries to connect to multiple devices (100's), around 20-30 at a time, using multiple threads and instances of the SecureFTPConnection. Using the Asynchronous methods, I have had the program lock on shutdown, even after disposing of all the instances, like some of them are still active and trying to connect. Since the Asynchronous methods use the thread pool, I have also noticed that some of them seem to be delayed in actually starting their work, and seem slower in general, so I get more timeout errors using that approach as opposed to calling the synchronous version and managing my own threads.
0 votes
by (161k points)
If Close(true) has been called on a SecureFTPConnection, you should not make subsequent calls to Close() - you'll get an exception.
0 votes
by (780 points)
This is not what I'm seeing (edtFTPnetPRO 8.5.0.20). Just for kicks, I called Close(True) and then called Close() directly afterwards 4-5 times. No exceptions were raised.

Again, the real issue is if I call Close(True) on a connection attempt to a server that IS NOT available (i.e. unplugged, powered off, disconnected from the network, etc.) In the code example listed previously, after calling Close(True) in this situation, if I were to be a good boy and call myFTP.Dispose as the very next line, the call to Dispose will block until the connection timeout actually expires, even though I just forced the close. I also see this if I immediately try to remove a handler as part of my cleanup. (All of this happens even if I DO NOT make a second call to Close().

If using the synchronous methods instead (by calling Connect on a worker thread and calling Close(True) on the parent thread), a subsequent call to Dispose will not block, but if I then Join the worker thread until it finishes, the join will block until the connection timeout expires, even though I tried to force the close from the parent. Right now I'm just forcing the worker thread to abort if it doesn't finish within a few seconds after trying to close the connection (which I'm not a fan of doing since it's not as clean).

I just renewed my support and upgraded to the latest version last week. Should I open an official support ticket instead of working through the forums?
0 votes
by (161k points)
I just renewed my support and upgraded to the latest version last week. Should I open an official support ticket instead of working through the forums?


Yes please - that will give you higher priority than forums posts.

Categories

...