Прогресс в получении неверного значения от фонового работника - PullRequest
1 голос
/ 22 сентября 2011

Я новичок в C #, и я все еще работаю и изучаю все это.

Я сделал этот код для индикатора выполнения при загрузке файла с ftp, и он действительно работает просто отлично. Но значение прогресса все неправильно. Похоже, что это значение байта как-то. Но странная вещь, когда я печатаю значение на экране, то оно печатает правильное значение.

private void frm_movie_db_Load(object sender, EventArgs e)
{
    if (!File.Exists("movies.list.gz"))
    {
        bg_worker.RunWorkerAsync();
    }
}

private void bg_worker_DoWork(object sender, DoWorkEventArgs e)
{
    string strDownloadFrom = "ftp://ftp.sunet.se/pub/tv+movies/imdb/movies.list.gz";
    string strDownloadTo = "movies.list.gz";

    try
    {
        FtpWebRequest request = (FtpWebRequest)WebRequest.Create(strDownloadFrom);

        request.Method = WebRequestMethods.Ftp.GetFileSize;
        request.Credentials = new NetworkCredential("anonymous", "");
        request.UsePassive = true;
        request.UseBinary = true;
        request.KeepAlive = true;

        Int64 intFileSize = request.GetResponse().ContentLength;
        Int64 intRunningByteTotal = 0;

        request = (FtpWebRequest)FtpWebRequest.Create(strDownloadFrom);
        request.Method = WebRequestMethods.Ftp.DownloadFile;
        request.Credentials = new NetworkCredential("anonymous", "");
        request.UsePassive = true;
        request.UseBinary = true;
        request.KeepAlive = false;

        FtpWebResponse response = (FtpWebResponse)request.GetResponse();
        Stream reader = response.GetResponseStream();

        Stream writer = new FileStream(strDownloadTo, FileMode.Create, FileAccess.Write, FileShare.None);
        byte[] byteBuffer = new byte[1024];

        int intByteSize = 0;
        int intProgressPct = 0;

        while ((intByteSize = reader.Read(byteBuffer, 0, byteBuffer.Length)) > 0)
        {
            if (intByteSize == 0)
            {
                intProgressPct = 100;
                bg_worker.ReportProgress(intProgressPct);
            }
            else
            {
                writer.Write(byteBuffer, 0, intByteSize);

                if (intByteSize + intRunningByteTotal <= intFileSize)
                {
                    intRunningByteTotal += intByteSize;
                    double dIndex = intRunningByteTotal;
                    double dTotal = byteBuffer.Length;
                    double dProgressPct = (double)(dIndex / dTotal);
                    intProgressPct = (int)dProgressPct;
                    bg_worker.ReportProgress(intProgressPct);
                }
            }
        }

        //reader.Close();
        //mem_stream.Close();
        //response.Close();
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }
}

private void bg_worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    //pb_download_files.Value = e.ProgressPercentage;
    lbl_progress_pct.Text = e.ProgressPercentage.ToString() + "%";
}

private void bg_worker_RunWorkerComplete(object sender, RunWorkerCompletedEventArgs e)
{
    pnlProgress.Visible = false;
}

Я надеюсь, что кто-то может помочь мне с этим, так как я уже сделал все, чтобы решить проблему самостоятельно.

С наилучшими пожеланиями Jesper

Ответы [ 3 ]

4 голосов
/ 22 сентября 2011

Вы полностью ошибаетесь при расчете процента прогресса: perc должен быть 100 x текущим / общим , поэтому вы используете неправильные значения.

Попробуйте с этим:

double dProgressPct = 100.0 * intRunningByteTotal / intFileSize;
bg_worker.ReportProgress((int)ProgressPct);

Чтение документации Microsoft :

public void ReportProgress(int percentProgress)

, где процентProgress - это процент от 0 до 100 завершенной фоновой операции.

1 голос
/ 22 сентября 2011

у вас есть:

double dTotal = byteBuffer.Length;
double dProgressPct = (double)(dIndex / dTotal);

Я думаю, что вы хотите:

double dProgressPct = (double)(dIndex / intFileSize );
1 голос
/ 22 сентября 2011
double dTotal = byteBuffer.Length;

Не присваивает общее количество байтов dTotal. byteBuffer - это буфер с постоянным размером 1024 байта. Попробуйте что-то вроде

double dTotal = reader.Length;

для получения длины в байтах потока.

...