Заполнение 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);
→ Ссылка