0

I have a C# program that checks a ftp directory for new files every x seconds. If a new file is found it is downloaded. That works fine. If I start the program without running the ftp server the program loops and returns a message that the server cannot be reached. Then I start the server and the program connects as it should. But if I quit the ftp server again my program gets stuck in the FtpWebResponse.

I have a using statement block in a try catch block to close all connections.

while (true)
{
    //...
    FtpFileList = null;
    while (FtpFileList == null)
    {
        FtpFileList = await GetFtpFileList(adress, user, password);
        await Task.Delay(3000);
    }
    await Task.Delay(27000);
    //...
}


public static async Task<List<string>> GetFtpFileList(string address, string user, string password)
{
    try
    {
        List<string> returnValue = new List<string>();
        FtpWebRequest request = (FtpWebRequest)WebRequest.Create(address);
        request.Method = WebRequestMethods.Ftp.ListDirectory;
        request.Credentials = new NetworkCredential(user, password);
        using (FtpWebResponse response = (FtpWebResponse)await request.GetResponseAsync()) //The program gets stuck here
        {
            Stream responseStream = response.GetResponseStream();
            StreamReader reader = new StreamReader(responseStream);
            while (reader.Peek() >= 0)
            {
                returnValue.Add(reader.ReadLine());
            }
        }
        AddToLogFile(DateTime.Now + ": " + "FTP directory updated");
        return returnValue;
    }
    catch (WebException e)
    {
        AddToLogFile(DateTime.Now + ": " + e.Message);
        return null;
    }
}

I expect the program to reconnect to the server after the connection was lost but instead it gets stuck.

Any help and hints how to solve that issue is appreciated.

  • I had trouble using HttpClient async methods when it receives exceptions. Try adding .ConfigureAwait(false) ... using (FtpWebResponse response = (FtpWebResponse)await request.GetResponseAsync().ConfigureAwait(false)) – TheMikeInNYC Aug 01 '19 at 14:42
  • @TheMikeInNYC Thanks for your reply. Unfortunately that did not solve the problem. It stills runs into the FtpWebResponse and won't move on after disconnecting the server. – Pietr Podschinski Aug 01 '19 at 15:03

2 Answers2

3

Just to let you know I solved the issue by implementing a workaround: Instead of using await request.GetResponseAsync() I use the normal GetResponse() method in another thread which works without any problems so far: await Task.Run(() => request.GetResponse())

0

Use FtpWebRequest.GetResponse instead of FtpWebRequest.GetResponseAsync ( as GetResponseAsync is not overridden in FtpWebRequest and comes from the base WebRequest class, where it seems to it can't handle some specific FTP use cases)

If you need to await something just replace this:

FtpWebRequest request = ...
var response = (FtpWebResponse) await request.GetResponseAsync();
return response;

with that:

var response = (FtpWebResponse) request.GetResponse();
return await Task.FromResult(response);
Dmitry Pavlov
  • 30,789
  • 8
  • 97
  • 121
  • `WebRequest.GetResponseAsync` only calls `BeginGetResponse` and `EndGetResponse`, which are implemented in `FtpWebRequest`, so the *"where it seems to it can't handle some specific FTP use cases"* is not well-founded (I do not question the fact there there *may be* a bug, but not the way your answer suggests). – Martin Prikryl Sep 15 '21 at 14:04
  • @MartinPrikryl yes, I thought so. But for some FTP servers the calls `BeginGetResponse` and `EndGetResponse` of the base `WebRequest` class seem to be not enough. Sync version `FtpWebRequest.GetResponse` works well for them. So it seems something needs to be revisited in async version of `FtpWebRequest` code of the begin/end implementations... – Dmitry Pavlov Sep 17 '21 at 15:53