0

I have a windows service with a timer. About 3 times a day the timer uploads files to different ftp servers. I set the timer, upload the files, then set the next time. This worked fine for a while, until I added another ftpserver for uploading files. When uploading to that ftpserver the project hangs at manualresetevent.waitone (even though the folder was uploaded) Here part of the code, let me know if more is needed.

Dim state As New FtpState
                    Dim request As FtpWebRequest = DirectCast(WebRequest.Create(target), FtpWebRequest)
                    request.Method = WebRequestMethods.Ftp.UploadFile

                    request.Credentials = mycredentials 

                    state.Request = request
                    state.FileName = fileName

                    ' Get the event to wait on.
                    waitObject = state.OperationComplete

                    ' Asynchronously get the stream for the file contents.
                    request.BeginGetRequestStream(New AsyncCallback(AddressOf EndGetStreamCallback), state)

                    ' Block the current thread until all operations are complete.
                    waitObject.WaitOne()

                    ' The operations either completed or threw an exception. 
                    If state.OperationException IsNot Nothing Then
                        Throw New Exception(state.OperationException.ToString)
                    Else

                        Publish.sendMail("Upload completed for filename:" & fileName & state.StatusDescription)
                    End If
                End If

This ftpserver works a little different than the others that I'm using and I'm not sure if thats the cause of the problem.

Here is the difference: I upload a zip folder (not just files) which can be quite large and soon after it's uploaded, it is being moved from that ftpserver.

(Whereas the other ftpservers leave the files on the ftpserver)

I think this problem only started once the zipfolder got larger.

I know that it is uploaded and then deleted from there.

So if the upload completed, why does it get stuck at waitone?

Here my endstreamcallback function

Private Shared Sub EndGetStreamCallback(ByVal ar As IAsyncResult)
    Dim state As ftpState = DirectCast(ar.AsyncState, ftpState)

    Dim requestStream As Stream = Nothing
    ' End the asynchronous call to get the request stream. 
    Try
        requestStream = state.Request.EndGetRequestStream(ar)
        ' Copy the file contents to the request stream. 
        Const bufferLength As Integer = 2048
        Dim buffer As Byte() = New Byte(bufferLength - 1) {}
        Dim count As Integer = 0
        Dim readBytes As Integer = 0
        Dim stream As FileStream = File.OpenRead(state.FileName)
        Do
            readBytes = stream.Read(buffer, 0, bufferLength)
            requestStream.Write(buffer, 0, readBytes)
            count += readBytes
        Loop While readBytes <> 0
        'Console.WriteLine("Writing {0} bytes to the stream.", count)
        ' IMPORTANT: Close the request stream before sending the request.
        requestStream.Close()
        ' Asynchronously get the response to the upload request.
        state.Request.BeginGetResponse(New AsyncCallback(AddressOf EndGetResponseCallback), state)
        ' Return exceptions to the main application thread. 
    Catch e As Exception
        Publish.sendMail("Could not get the request stream.")
        state.OperationException = e
        state.OperationComplete.[Set]()
        Return
    End Try

End Sub

' The EndGetResponseCallback method
' completes a call to BeginGetResponse.

   Private Shared Sub EndGetResponseCallback(ByVal ar As IAsyncResult)
    Dim state As FtpState = DirectCast(ar.AsyncState, FtpState)
    Dim response As FtpWebResponse = Nothing
    Try
        response = DirectCast(state.Request.EndGetResponse(ar), FtpWebResponse)
        response.Close()
        state.StatusDescription = response.StatusDescription
        ' Signal the main application thread that  
        ' the operation is complete.
        state.OperationComplete.[Set]()
        ' Return exceptions to the main application thread. 
    Catch e As Exception
        Publish.sendMail("Error getting response.")
        state.OperationException = e
        state.OperationComplete.[Set]()
    End Try
End Sub
  • 1
    Strong odds that you haven't tested the code yet when the EndGetStreamCallback() method fails to do its job, for whatever reason. There is just no point in using BeginGetRequestStream() when you are going to wait for it to complete. Eliminate failure modes by using the non-asynchronous method instead. Use GetRequestStream(). – Hans Passant Sep 02 '14 at 09:10
  • I don't understand. I upload alot of files to many different servers, only this specific server is one zipfolder. I can't set the timer to start again if it wasn't finished uploading. – user3821898 Sep 02 '14 at 12:57
  • see my edited post for the endstreamcallback function – user3821898 Sep 02 '14 at 13:12
  • code I got from here: http://msdn.microsoft.com/en-us/library/system.net.ftpwebrequest.aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-4 ( for a whole year this is working without any problems, only since adding this ftpserver it hangs – user3821898 Sep 02 '14 at 13:23
  • You don't call Set in the non-error case. Is the code complete?! – usr Sep 02 '14 at 14:16
  • I added more of the code the endgetresponse function – user3821898 Sep 02 '14 at 16:03
  • I changed my code for uploading the zipfolder to Try Using WC As New WebClient WC.Credentials = mycredentials WC.UploadFile(target, fileName) End Using Catch ex As Exception Publish.sendMail("Error in uploadZip:" & ex.Message.ToString) End Try it works, but gives me error message The underlying connection was closed: An unexpected error occurred on a receive – user3821898 Sep 02 '14 at 19:50

0 Answers0