У меня следующая проблема:
Я использую методы C # ftp для автоматизации отправки файлов на FTP-серверы. Программа постоянно работает, проверяя предопределенные каталоги. Если он находит файлы в каталоге, он должен загрузить их на определенный FTP-сервер. Существует около 80 каталогов, и в большинстве случаев программе есть чем заняться. Все отлично работает, кроме следующего сценария:
- Файл загружается.
- Ошибка при загрузке: удаленный хост отключен, квота превышена или что-то подобное.
- Предпринята попытка загрузить файл еще раз, и ошибка повторяется.
Предпринята попытка загрузить файл на третий, четвертый, ... раз, а затем эту строку кода:
Поток requestStream = ftpRequest.GetRequestStream ();
выдает WebException со статусом: Undefined и description: срок для этой операции достигнут (или что-то подобное - мне пришлось перевести это с польского). Пока создается это исключение WebException, запрос ftp на другие серверы (файлы из разных каталогов) выполняется успешно, поэтому похоже, что существует проблема только с подключением к этому одному серверу ftp.
Все это приводит к тому, что дальнейшая попытка загрузки файла не удалась. Однако выгрузка этого файла через другой ftp-клиент возможна. Когда я перезапускаю программу, все работает без сбоев. Должен ли я как-то вручную освободить ресурс ftp? Я использую свойство KeepAlive для FtpWebRequest со значением true ..
Буду очень признателен, если кто-нибудь сможет пролить свет на эту проблему.
Отредактировано:
Я последовал совету Дэвида и нашел место, где не вызывал метод Close () для requestStream, я исправил его, но проблема снова возникла.
Тогда я вставлю код. Вот часть метода, который загружает файл на сервер. Если это не удается, делается другая попытка, что-то вроде:
while (retryCounter++ < retryNumber)
{
//upload file,
//if succeeded, break
}
внутри блока while:
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());
}
Итак, снова сценарий следующий:
1. Файл загружается и возникает исключение System.Net.Sockets.SocketException.
2. Еще одна попытка, и System.Net.Sockets.SocketException повторяется.
3. Всегда перед вызовом метода uploadfile я проверяю, работает ли удаленный сервер и все ли в порядке, пытаясь составить список удаленных каталогов. И с этого момента, позвонив
ftpRequest.GetResponse () (где ftpRequest.Method - WebRequestMethods.Ftp.ListDirectory) Я получаю исключение WebException со статусом: Undefined и description: ограничение по времени для этой операции достигнуто. Когда я перезапускаю приложение, проблема исчезает.
Я не могу найти другого места, где потоки не освобождаются должным образом, и не знаю, что делать дальше ..