Показать прогресс с помощью загрузки WebClient - PullRequest
2 голосов
/ 24 марта 2012

Я тестирую некоторые функции класса WebClient и решил посмотреть, как работает DownloadProgressChanged, поэтому я составил такой код:

static void Main(string[] args)
{
  WebClient client = new WebClient();
  client.Proxy = null;
  client.BaseAddress = "ftp://ftp.xxxxxxx.com";
  CredentialCache cache = new CredentialCache();
  NetworkCredential credential = new NetworkCredential("userxxx", "passxxxx");
  client.Credentials = credential;
  client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
  Uri remoteFile;
  Uri.TryCreate("/public_html/folderxxxx/Pictures/Product/Resized/1.jpg", System.UriKind.Relative, out remoteFile);

  client.DownloadFileAsync(remoteFile, "1.jpg");
  System.Diagnostics.Process.Start("1.jpg");
  Console.ReadLine();
}

static void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
  Console.WriteLine(e.ProgressPercentage.ToString());
}

Когда я запускаю это приложение, это то, что я вижу как прогресс:

Console App Shows Progress

Ничего особенного. Бен Албахари предлагает использовать новый поток вместо использования асинхронного метода, и этот обработчик событий полезен, когда вы фактически используете асинхронный метод.

Так, как я могу действительно показать Прогресс?

EDIT:

Согласно MSDN это должно быть сделано:

Пассивная передача файлов по FTP всегда будет отображать процент выполнения ноль, так как сервер не отправил размер файла. Чтобы показать прогресс, Вы можете изменить FTP-соединение на активное, переопределив Виртуальный метод GetWebRequest:

Пример кода:

   internal class MyWebClient:WebClient{
        protected override WebRequest GetWebRequest(Uri address) {
            FtpWebRequest req = (FtpWebRequest)base.GetWebRequest(address);
            req.UsePassive = false;
            return req;
        }
    }

Что я и сделал, но возникает та же проблема:

enter image description here

Ответы [ 3 ]

3 голосов
/ 24 марта 2012

Из MSDN:

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

Источник

1 голос
/ 19 апреля 2012

Похоже, что многие задают этот вопрос.

Насколько я могу судить, ваш сервер будет сообщать о ходе выполнения, только если он установлен, вы разрешаете активные подключения.Похоже, что PASV (пассивный FTP) может быть включен или отключен на сервере.И используемый режим должен определяться тем, какой сервер настроен для использования и что находится между сервером и клиентом.

РЕДАКТИРОВАТЬ: я включил System.Net.Tracing в моем проекте и пробовал как пассивный, так и активный режимы, а нетолько оба работают как положено ... TotalBytes по-прежнему -1, поэтому я думаю, что примечание по MSDN

http://msdn.microsoft.com/en-US/library/system.net.webclient.downloadprogresschanged(v=vs.80).aspx

ошибочно или мы что-то упустили.

http://compnetworking.about.com/cs/protocolsftp/g/bldef_pasv.htm

http://slacksite.com/other/ftp.html

http://fetchsoftworks.com/fetch/help/Contents/Concepts/ActiveAndPassive.html

Таким образом, переопределение метода WebRequest не будет иметь значения, если сервер не использует активные подключения.

Однако ... как вы можете видеть из своей командной строки, он правильно сообщает о полученных байтах.

Узнайте размер файла, и вас нет ...

Я предполагаю, что есть более эффективный метод, но ... Я использовал FtpWebRequest, чтобы получить размер файла перед загрузкой, а затем запустил DownloadFileAsync и передал размер файла в DownloadProgressCallback, используя:

Client.DownloadProgressChanges += (sender, e) => DownloadProgressCallback( fileSize, e)

Надеюсьэто помогает:)

1 голос
/ 24 марта 2012

Читали ли вы документацию ??

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

internal class MyWebClient:WebClient{
        protected override WebRequest GetWebRequest(Uri address) {
            FtpWebRequest req = (FtpWebRequest)base.GetWebRequest(address);
            req.UsePassive = false;
            return req;
        }
    }
...