Заполнение ProgressBar
Есть такой метод:
public static async void DownloadFile(string filename, IProgress<decimal> progress)
{
progress.Report(0m);
using (WebClient request = new WebClient())
{
request.Credentials = new NetworkCredential("login", "password");
byte[] fileData = request.DownloadData("ftp://...." + filename);
var pathNormalize = $"{MyPath.Desktop}\\{filename}".Replace("\r", string.Empty);
using (var file = File.Create(pathNormalize))
{
await file.WriteAsync(fileData, 0, fileData.Length);
var percent = 100m * ((decimal)file.Position / file.Length);
progress.Report(percent);
}
}
}
Вызываю так:
var progress = new Progress<decimal>((p) =>
{
progressBar1.Value = (int)Convert.ToDecimal(p)));
if (progressBar1.Value >= progressBar1.Maximum)
{
progressBar1.Value = 0;
MessageBox.Show("Completed!");
}
});
FTP.DownloadFile(name, progress);
Проблема:
При вызове метода DownloadFile блокируется основной поток и в конце значение ProgressBar становится 100.
Если вызывать так:
Task.Run(() => FTP.DownloadFile(name, progress));
Основной поток не блокируется, но ProgressBar также перескакивает к значению 100.
При всём при этом, после скачивание файла не показывает текст Completed!.
Нашел на просторах интернета уже не один пример скачивания файла с FTP, но ни один так и не удалось подружить с ProgessBar.
Подскажите, пожалуйста, в чем проблема. Пытаюсь разобраться уже много времени.
upd:
public static void DownloadFile(string filename, DownloadProgressChangedEventHandler DownloadProgressChanged, System.ComponentModel.AsyncCompletedEventHandler DownloadCompleted)
{
Thread thread = new Thread(() =>
{
using (WebClient request = new WebClient())
{
request.Credentials = new NetworkCredential("login", "password");
request.DownloadProgressChanged += DownloadProgressChanged;
request.DownloadFileCompleted += DownloadCompleted;
var pathNormalize = $"{MyPath.Desktop}\\{filename}".Replace("\r", string.Empty);
request.DownloadFileAsync(new Uri("ftp://....." + filename), pathNormalize);
}
});
thread.Start();
}
private void DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
this.BeginInvoke((MethodInvoker)delegate {
progressBar1.Value = e.ProgressPercentage;
});
}
private void DownloadCompleted(object sender, AsyncCompletedEventArgs e)
{
this.BeginInvoke((MethodInvoker)delegate {
MessageBox.Show("Completed!");
});
}
Ответы (1 шт):
Автор решения: Максим
→ Ссылка
Проблема оказалось в том, что при скачивании с FTP с отображением прогресса, нужно для начала узнать размер файла.
Вот рабочий код:
public static void DownloadFile(string filename, DownloadProgressChangedEventHandler DownloadProgressChanged, System.ComponentModel.AsyncCompletedEventHandler DownloadCompleted)
{
Thread thread = new Thread(() =>
{
var request = (FtpWebRequest)WebRequest.Create("ftp://......" + filename);
request.Credentials = new NetworkCredential("login", "password");
request.Method = WebRequestMethods.Ftp.GetFileSize;
var response = (FtpWebResponse)request.GetResponse();
using (Stream responseStream = response.GetResponseStream())
{
MainForm.bytes = response.ContentLength;
}
using (WebClient request_ = new WebClient())
{
request_.Credentials = new NetworkCredential("login", "password");
request_.DownloadProgressChanged += DownloadProgressChanged;
request_.DownloadFileCompleted += DownloadCompleted;
var pathNormalize = $"{MyPath.Desktop}\\{filename}".Replace("\r", string.Empty);
request_.DownloadFileAsync(new Uri("ftp://....." + filename), pathNormalize);
}
});
thread.Start();
}
private void DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
this.BeginInvoke((MethodInvoker)delegate {
progressBar1.Value = (int)(((float)e.BytesReceived / (float)bytes) * 100.0);
});
}
private void DownloadCompleted(object sender, AsyncCompletedEventArgs e)
{
this.BeginInvoke((MethodInvoker)delegate {
MessageBox.Show("Completed!");
});
}
//где-то вызов
FTP.DownloadFile(name, DownloadProgressChanged, DownloadCompleted);