【问题标题】:Calculate progressbar value for multiple file upload计算多个文件上传的进度条值
【发布时间】:2016-11-16 23:59:14
【问题描述】:

我为多个文件上传编写了一个小脚本,包括用于状态信息的进度条。
现在我想知道如何计算有关上传的所有选定文件的 pogressbar 值。
文件上传使用初始化如下的 BackgroundWorker:

public Form()
{
    worker = new BackgroundWorker();
    worker.WorkerReportsProgress = true;
    worker.WorkerSupportsCancellation = true;

    worker.DoWork += new DoWorkEventHandler(worker_DoWork);
    worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
    worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
}

单击按钮打开文件对话框,BackgroundWorker 开始工作:

private void button1_Click(object sender, EventArgs e)
{
        if (worker.IsBusy)
        {
            worker.CancelAsync();
        }
        else
        {
            OpenFileDialog od = new OpenFileDialog();
            od.Multiselect = true;
            if (od.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                if (progressBar1.Value == progressBar1.Maximum)
                {
                    progressBar1.Value = progressBar1.Minimum;
                }

                string ftpServerIP = textBox1.Text;
                string ftpUserID = textBox2.Text;
                string ftpPassword = textBox3.Text;

                List<object> arguments = new List<object>();
                arguments.Add(progressBar1.Value);
                arguments.Add(od.FileNames);
                arguments.Add(ftpServerIP);
                arguments.Add(ftpUserID);
                arguments.Add(ftpPassword);

                worker.RunWorkerAsync(arguments);
            }
        }
}

BackgroundWorker 开始工作时,建立 FTP 连接以从 FileOpenDialog 传输所有文件。以下代码的末尾是我的计算进度条示例,必须对其进行更改以满足总文件大小:

private void worker_DoWork(object sender, DoWorkEventArgs e)
    {
        List<object> arguments = e.Argument as List<object>;
        int percentFinished = (int)arguments[0];
        string[] fileNames = arguments[1] as string[];
        string ftpServerIP = arguments[2] as string;
        string ftpUserID = arguments[3] as string;
        string ftpPassword = arguments[4] as string;

        while (!worker.CancellationPending && percentFinished < 100)
        {
            foreach (string fileName in fileNames)
            {
                FileInfo fileInf = new FileInfo(fileName);

                // Create FtpWebRequest object from the Uri provided
                reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + ftpServerIP + "/" + fileInf.Name));

                // FTP Credentials
                reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);

                // By default KeepAlive is true, where the control connection is not closed after a command is executed.
                reqFTP.KeepAlive = false;

                // Specify the command to be executed.
                reqFTP.Method = WebRequestMethods.Ftp.UploadFile;

                // Specify the data transfer type.
                reqFTP.UseBinary = true;

                // Notify the server about the size of the uploaded file
                reqFTP.ContentLength = fileInf.Length;

                // The buffer size is set to 2kb
                int buffLength = 2048;

                byte[] buff = new byte[buffLength];

                int contentLen;

                // Opens a file stream (System.IO.FileStream) to read the file to be uploaded
                FileStream fs = fileInf.OpenRead();

                try
                {
                    // Stream to which the file to be upload is written
                    Stream strm = reqFTP.GetRequestStream();

                    // Read from the file stream 2kb at a time
                    contentLen = fs.Read(buff, 0, buffLength);

                    // Until Stream content ends
                    while (contentLen != 0)
                    {
                        // Write Content from the file stream to the FTP Upload Stream
                        strm.Write(buff, 0, contentLen);
                        contentLen = fs.Read(buff, 0, buffLength);
                    }

                    // Close the file stream and the Request Stream
                    strm.Close();
                    fs.Close();

                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Upload Error");
                }
            }

            // ToDO: Calculate progressBar
            percentFinished++;
            worker.ReportProgress(percentFinished);
            System.Threading.Thread.Sleep(50);
        }
        e.Result = percentFinished;
    }


解决方案
我只需要删除超时并且工作人员报告正确的值。

 percentFinished++;
 worker.ReportProgress(percentFinished);
 //System.Threading.Thread.Sleep(50);

【问题讨论】:

    标签: c# winforms file-upload progress-bar


    【解决方案1】:

    我不确定我是否理解正确,但让我们试一试。 由于您的string[] 数组中有要上传的项目数,因此您可以将ProgressBarMaximum 设置为开头的元素数。

    ProgressBar1.Value = 0;
    ProgressBar1.Maximum = fileNames.Length;
    

    在每个循环结束时,您可以简单地使用 ProgressBar1.Value += 1; 递增 ProgressBar 的值

    private void worker_DoWork(object sender, DoWorkEventArgs e)
    {
    
        //Blah blah blah
        string[] fileNames = arguments[1] as string[];
    
        ProgressBar1.Value = 0;
        ProgressBar1.Maximum = fileNames.Length;
    
    
        while (!worker.CancellationPending && percentFinished < 100)
        {
            foreach (string fileName in fileNames)
            {
                //Blah blah blah
                ProgressBar1.Value += 1;
            }
        }
    }
    

    我希望你的问题是正确的。


    编辑:对于每个文件,您可能可以玩转BackgroundWorkerProgressChanged 事件。

    private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        progressBar.Value = e.ProgressPercentage;
    }
    

    但请确保您的BackgroundWorkerWorkerReportsProgress 设置为true

    backgroundWorker2.WorkerReportsProgress = true;
    

    【讨论】:

    • 你在哪里关注percentFinished?进度条通过百分比值。当它等于 100% 时,它就完成了。 progressBar1.Maximum 始终为 100。如何考虑 fileNames.Length 和百分比来计算进度?
    • 这就是我的意思,您不需要使用单独的变量等,因为您的代码中有“总元素”和“映射元素”。进度条的最大值不必是 100,您可以简单地将其最大值设置为数组的元素数,并在每次完成上传时将值增加一。我是不是弄错了你的逻辑?另外,如果您想将百分比计算为数值,则类似于int percResult = mappedElements * 100 / totalElements;
    • 这就是重点:当我只有一个大小为 50 MB 的文件时,当我使用您的逻辑时,进度条将为零,直到上传 50 MB,然后切换到 1。对吗?我的目的是识别已经上传的文件大小,例如20 MB 的 50 MB 的一个文件并在进度条上显示 40% 上传...
    • 哦,现在我明白你的意思了。你试过玩BackgroundWorkerProgressChanged 事件吗?我正在更新我的答案,以便为您提供帮助
    • 在顶部发布了解决方案,以便它适用于所有阅读本文的人。
    猜你喜欢
    • 1970-01-01
    • 2012-07-17
    • 2018-06-30
    • 2015-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-07
    • 2011-12-07
    相关资源
    最近更新 更多