从后台工作者获取错误值的进度

发布于 2024-12-05 23:08:37 字数 2978 浏览 4 评论 0原文

我是 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;
}

我希望有人可以帮助我解决这个问题,因为到目前为止我已经尽了一切努力来解决这个问题。

此致 杰斯珀

I'm new in c# and i'm still working way through and learning it all.

I have made this code for a progress bar when downloading a file from ftp, and it actually working just fine. But progress value is all wrong. It looks like it is byte value somehow. But the weird thing is when I print the value to the screen, then it prints the correct value.

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;
}

I hope someone can help me with this, as i've done everything so far to fix the problem myself.

Best regards
Jesper

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

余厌 2024-12-12 23:08:37

您对百分比进度计算完全错误:perc 必须是
100 x 当前/总计,因此您使用了错误的值。

尝试这样做:

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

阅读 Microsoft 文档

public void ReportProgress(int percentProgress)

其中 percentageProgress 是已完成的后台操作的百分比(从 0 到 100)。

You're completely mistaken on percentage progress calculation: perc must be
100 x current / total, so you're using wrong values.

Try with this:

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

Read Microsoft documentation:

public void ReportProgress(int percentProgress)

where percentageProgress is the percentage, from 0 to 100, of the background operation that is complete.

层林尽染 2024-12-12 23:08:37
double dTotal = byteBuffer.Length;

不将总字节分配给 dTotal。 byteBuffer 是一个大小恒定为 1024 字节的缓冲区。尝试类似

double dTotal = reader.Length;

检索流的字节长度。

double dTotal = byteBuffer.Length;

Does not assign the total bytes to dTotal. byteBuffer is a buffer with a constant size of 1024 bytes. Try something like

double dTotal = reader.Length;

to retrieve the length in bytes of the stream.

滥情稳全场 2024-12-12 23:08:37

你有:

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

我想你想要:

double dProgressPct = (double)(dIndex / intFileSize );

you have:

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

I think you want:

double dProgressPct = (double)(dIndex / intFileSize );
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文