3 Stimmen

Hochladen von Dateien mit c# ftp Methoden Ergebnisse in webexception. Das Problem verschwindet nach einem Neustart des Programms

Ich habe folgendes Problem: Ich verwende C#-ftp-Methoden, um das Senden von Dateien an FTP-Server zu automatisieren. Das Programm läuft ständig und überprüft vordefinierte Verzeichnisse. Wenn es Dateien in einem Verzeichnis findet, soll es diese auf einen definierten FTP-Server hochladen. Es gibt etwa 80 Verzeichnisse und die meiste Zeit hat das Programm etwas zu tun. Alles funktioniert gut, bis auf das folgende Szenario:

  1. Die Datei wird gerade hochgeladen.
  2. Beim Hochladen tritt ein Fehler auf: Der Remote-Host ist ausgefallen, die Quote ist überschritten oder ähnliches.
  3. Bei einem erneuten Versuch, die Datei hochzuladen, tritt der Fehler erneut auf.
  4. Es wird versucht, die Datei zum dritten, vierten, ... Mal hochzuladen und dann diese Codezeile:

    Stream requestStream = ftpRequest.GetRequestStream();

wirft WebException mit Status: Undefined, and description: the time limit for this operation has been reached (oder so ähnlich - ich musste das aus dem Polnischen übersetzen). Während diese WebException ausgelöst wird, sind FTP-Anfragen an andere Server (Dateien aus verschiedenen Verzeichnissen) erfolgreich, also sieht es so aus, als gäbe es nur ein Problem mit der Verbindung zu diesem einen FTP-Server.

Dies führt dazu, dass kein weiterer Versuch, die Datei hochzuladen, erfolgreich ist. Das Hochladen dieser Datei über einen anderen FTP-Client ist jedoch möglich. Wenn ich das Programm neu starte, läuft alles reibungslos. Sollte ich die ftp-Ressource irgendwie manuell freigeben? Ich verwende die KeepAlive-Eigenschaft von FtpWebRequest, die auf true. gesetzt ist.

Ich wäre sehr dankbar, wenn jemand etwas Licht in dieses Problem bringen könnte.

Bearbeitet:

Ich habe Davids Hinweis befolgt und die Stelle gefunden, an der ich die Close()-Methode für den requestStream nicht aufgerufen habe, ich habe es behoben, aber das Problem trat erneut auf.

Ich werde dann einen Code einfügen. Hier ist ein Teil der Methode, die die Datei auf den Server hochlädt. Wenn es fehlschlägt, wird ein weiterer Versuch unternommen, etwas wie:

while (retryCounter++ < retryNumber)
{
  //upload file,
  //if succeeded, break
}

innerhalb des while-Blocks gibt es:

FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create(remoteFileName);
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = true;
ftpRequest.Credentials = new NetworkCredential(UserName, Password);
ftpRequest.ReadWriteTimeout = SendTimeout;
ftpRequest.Timeout = ConnectTimeout;
ftpRequest.KeepAlive = true;
ftpRequest.Proxy = null;
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile;

Stream requestStream = null;

try
{

  using (MemoryStream fileStream = new MemoryStream(localFile))
  {
    byte[] buffer = new byte[BufferSize];

    int readCount = fileStream.Read(buffer, 0, BufferSize);
    int bytesSentCounter = 0;

     while (readCount > 0)
     {
         requestStream.Write(buffer, 0, readCount);
         bytesSentCounter += readCount;

         readCount = fileStream.Read(buffer, 0, BufferSize);
         System.Threading.Thread.Sleep(100);

     }
}

requestStream.Close();
requestStream = null;

FtpWebResponse response = (FtpWebResponse)ftpRequest.GetResponse();
FtpStatusCode code = response.StatusCode;
string description = response.StatusDescription;
response.Close();

_logger.Information("Upload file result : status code {0}, status description {1}", code, description);

if (code == FtpStatusCode.ClosingData)
{
    _logger.Information("File {0} uploaded successfully", localFileName);
}  
else
{
    _logger.Error("Uploading file {0} did not succeed. Status code is {1}, description  {2}", localFileName, code, description);
}

}   
catch (WebException ex)
{

    if (requestStream != null)
        requestStream.Close();

    ftpRequest.Abort();

    FtpStatusCode code = ((FtpWebResponse)ex.Response).StatusCode;
    string description = ((FtpWebResponse)ex.Response).StatusDescription;

   _logger.Error("A connection to the ftp server could not be established. Status code: {0}, description: {1} Exception: {2}. Retrying...", code, description, ex.ToString());

}

Das Szenario ist also wieder folgendes:
1. Die Datei wird hochgeladen und eine System.Net.Sockets.SocketException tritt auf.
2. Ein weiterer Versuch wird unternommen und System.Net.Sockets.SocketException tritt erneut auf.
3. Bevor ich die uploadfile-Methode aufrufe, prüfe ich immer, ob der entfernte Server läuft und alles in Ordnung ist, indem ich versuche, das entfernte Verzeichnis aufzulisten. Und von nun an, durch den Aufruf von ftpRequest.GetResponse() (wobei ftpRequest.Method gleich WebRequestMethods.Ftp.ListDirectory ist) erhalte ich eine WebException mit Status: Undefiniert und Beschreibung: Das Zeitlimit für diesen Vorgang wurde erreicht. Wenn ich die Anwendung neu starte, verschwindet das Problem.

Ich kann keine andere Stelle finden, an der die Streams nicht ordnungsgemäß freigegeben werden, und habe keine Ahnung, was ich als nächstes tun soll.

1voto

David Schmitt Punkte 56455

Sind Sie sicher, dass Sie den Stream korrekt schließen und somit alle zugrunde liegenden Ressourcen ordnungsgemäß freigeben?

Wenn nicht, könnte dies die Ursache für Ihr Problem sein, wenn Sie nach wiederholten Fehlern an eine Grenze stoßen (z. B. offene Steckdosen).

1voto

NightOwl888 Punkte 52922

Sie müssen sicherstellen, dass Sie Stream.Close(), Request.Close() und Response.Close() in einen finally-Block setzen, da sie sonst im Fehlerfall übersprungen werden. Denken Sie daran, dass Sie beim Umgang mit externen Ressourcen, z. B. über ein Netzwerk, mit Fehlern rechnen müssen, da diese sicherlich irgendwann auftreten werden.

try 
{ 
    processing here...
} 
finally
{
     requestStream.Close(); 
     requestStream = null;
}

0voto

Dan Byström Punkte 8850

Eine mögliche Fehlerquelle, auf die ich gestoßen bin, ist das wiederholte Erstellen eines neuen "NetworkCredential". Dann erhalten Sie nach einer Weile eine Ausnahme.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X