Ошибка при закрытии потока ftp в C # - PullRequest
1 голос
/ 26 марта 2009

Я пытаюсь отменить операцию загрузки. Мой сценарий выглядит следующим образом:

Когда пользователь нажимает кнопку «Отменить загрузку», это действие вызывает исключение в функции загрузки, которое выглядит следующим образом:

        try
        {
            reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + uri + "/" + fileName));
            reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
            reqFTP.UseBinary = true;
            reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
            reqFTP.UsePassive = true;

            response = (FtpWebResponse)reqFTP.GetResponse();
            ftpStream = response.GetResponseStream();
            _isItOutputStream = true;
            string dataLengthString = response.Headers["Content-Length"];
            int dataLength = 0;
            if (dataLengthString != null)
            {
                dataLength = Convert.ToInt32(dataLengthString);
            }

            long cl = response.ContentLength;
            int bufferSize = 4048;
            int readCount;
            byte[] buffer = new byte[bufferSize];
            readCount = ftpStream.Read(buffer, 0, bufferSize);
            outputStream = new FileStream(filePath + "\\" + fileName, FileMode.Create);
            bool first = true;
            while (readCount > 0)
            {
                outputStream.Write(buffer, 0, readCount);
                _actualDownloaded += readCount;
                if (this.InvokeRequired)
                {
                    ProgressBarDel _progressDel = new ProgressBarDel(ProgressBar);
                    this.Invoke(_progressDel, new object[] { _actualDownloaded, first });
                }
                first = false;
                readCount = ftpStream.Read(buffer, 0, bufferSize);
            }
            ftpStream.Close();
            outputStream.Close();
            response.Close();
            _isItOutputStream = false;
            return true;
        }
        catch (Exception ee)
        {
            _downloadException = ee.Message;
            if (response != null)
            {

                outputStream.Close();
                ftpStream.Close();
                response.Close();
            }
            return false;
        }

В строке "ftpStream.Close()" здесь выдается исключение ...

Текст исключения:

Удаленный сервер возвратил ошибку: (450) Файл недоступен (например, файл занят)

где он открывает файл для загрузки, как я написал "outputStream = new FileStream(filePath + "\\" + fileName, FileMode.Create);" скачать -> отменить загрузку -> скачать -> отменить загрузку -> загрузить

если этот сценарий произошел, приложение зависает. я не знаю, как закрыть поток и ответ, чтобы я мог остановить загрузку, а затем удалить созданный файл, чтобы загрузить снова.

Thnx

Ответы [ 2 ]

3 голосов
/ 26 марта 2009

Строка, которая, по-видимому, вызывает ваше исполнение, приведена ниже и является результатом того, что FTP-сервер не находит нужный файл. Это ситуация, которая может легко случиться снова, поэтому, возможно, стоит поместить блок try / catch вокруг этой отдельной строки или использовать catch для конкретного генерируемого исключения.

ftpStream = response.GetResponseStream();

В данный момент в вашем блоке catch вы используете outputStream.Close (), но если исключение произойдет в строке выше, outputStream будет нулевым. По крайней мере, вы должны изменить порядок закрытия объектов в блоке catch и проверить их на null.

if(response != null) {
    response.Close();
}

if(ftpStream != null) {
    ftpStream.Close();
}

if(outputStream != null) {
    outputStream.Close();
}
1 голос
/ 26 марта 2009

Хорошо, сначала поставьте закрытие в блок, наконец.

Поэтому убедитесь, что ваш код подобен этому, чтобы гарантировать, что потоки закрыты, несмотря ни на что.

try
{
   //Your existing logic
   //Don't need to close the streams/etc
}
catch
{
   //Just do what you need to with the exception
}
finally
{
   //This is always called
   if (response != null)
      response.Close();
   if(outputStream != null)
      outputStream.Close();
   if(ftpStream != null)
      ftpStream.Close();
} 

Обернуть эту строку в попытку поймать

ftpStream = response.GetResponseStream();

Это должно быть хорошо, пока эти вызовы Close вызываются, где ваша логика отмены? Я ожидаю увидеть флаг в цикле, который устанавливается, когда пользователь нажимает кнопку. например,

while (readCount > 0 && !_shouldExit)
{
   outputStream.Write(buffer, 0, readCount);
  _actualDownloaded += readCount;
  if (this.InvokeRequired)
  {
    ProgressBarDel _progressDel = new ProgressBarDel(ProgressBar);
    this.Invoke(_progressDel, new object[] { _actualDownloaded, first });
  }
  first = false;
  readCount = ftpStream.Read(buffer, 0, bufferSize);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...