c#如何根据文件数量控制进度条

c#根据文件的数量来控制进度条,也就是说,复制完一个文件,进度条前进一点,进度条的最大值是文件的数量... c#根据文件的数量来控制进度条,也就是说,复制完一个文件,进度条前进一点,进度条的最大值是文件的数量 展开
 我来答
百度网友8d17b9d
推荐于2016-07-07 · TA获得超过280个赞
知道小有建树答主
回答量:161
采纳率:100%
帮助的人:181万
展开全部

说实话,关于进度条的解决方案很多,我暂且假定你在做Winform程序开发。

如果你使用的StatusBar中的进度条的话,你可以不考虑多线程更新UI的问题,因为它本身已经在内部实现了外部线程更新UI控件的逻辑。 但是如果你使用普通的Progressbar控件,那你就得自己处理这部分逻辑,因为控件只能在其所在的UI中更新,如果你想在其它线程中更新那你得用控件上的BeginInvoke方法, 当然还有其它的解决方案。

 

方案1:

using System;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using System.Threading;
using System.Threading.Tasks;
namespace AskAnswers
{
    public class ShowProgressStatus : Form
    {
        [STAThread]
        static void Main()
        {
            Application.Run(new ShowProgressStatus());
        }
        public ShowProgressStatus()
        {
            InitializeComponent();
        }
        /// <summary>
        ///    Required method for Designer support - do not modify
        ///    the contents of this method with an editor
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.label1 = new System.Windows.Forms.Label();
            this.progressBar1 = new System.Windows.Forms.ProgressBar();
            this.btnProcess = new System.Windows.Forms.Button();
            this.textBox1 = new System.Windows.Forms.TextBox();
            
            //@design this.TrayHeight = 0;
            //@design this.TrayLargeIcon = false;
            //@design this.TrayAutoArrange = true;
            label1.Location = new System.Drawing.Point(32, 40);
            label1.Text = "Progress Value";
            label1.Size = new System.Drawing.Size(88, 24);
            label1.TabIndex = 2;
            
            progressBar1.Maximum = 10;
            progressBar1.Location = new System.Drawing.Point(8, 312);
            progressBar1.Minimum = 0;
            progressBar1.TabIndex = 0;
            progressBar1.Value = 0;
    
            //We have calculated the excat size which will result in only 20 boxes to be drawn
            
            progressBar1.Size = new System.Drawing.Size(520, 40);
            progressBar1.Step = 1;
            
            btnProcess.Location = new System.Drawing.Point(152, 168);
            btnProcess.Size = new System.Drawing.Size(144, 48);
            btnProcess.TabIndex = 1;
            btnProcess.Text = "Process";
            btnProcess.Click += new System.EventHandler(btnProcess_Click);
            
            textBox1.Location = new System.Drawing.Point(136, 40);
            textBox1.Text = "0";
            textBox1.TabIndex = 3;
            textBox1.Size = new System.Drawing.Size(184, 20);
            this.Text = "Display Progress Status";
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.ClientSize = new System.Drawing.Size(616, 393);
            this.StartPosition = FormStartPosition.CenterScreen;
            
            this.Controls.Add(textBox1);
            this.Controls.Add(label1);
            this.Controls.Add(btnProcess);
            this.Controls.Add(progressBar1);
        }
        void btnProcess_Click(object sender, EventArgs e)
        {
            if (isProcessRunning)
            {
                MessageBox.Show("A process is already running.");
                return;
            }
            string[] files = Directory.GetFiles(@"c:\", "*");
            var filesCount = files.Length;
            progressBar1.Maximum = filesCount;
            Thread.Sleep(50);
            Thread backgroundThread = new Thread(
                new ThreadStart(() =>
                {
                    isProcessRunning = true;
                    for (int n = 0; n < filesCount; n++ )
                    {
                        // 模拟拷贝文件过程 
                        Thread.Sleep(100);
                        Console.WriteLine(files[n]);
                        progressBar1.BeginInvoke(
                            new Action(() =>
                                {
                                    progressBar1.Value = n + 1;
                                }
                        ));
                    }
                    MessageBox.Show("Thread completed!");
                    progressBar1.BeginInvoke(
                            new Action(() =>
                            {
                                progressBar1.Value = 0;
                            }
                    ));
                    isProcessRunning = false;
                }
            ));
            backgroundThread.Start();
        }
        private System.Windows.Forms.Button btnProcess;
        private System.ComponentModel.Container components;
        private System.Windows.Forms.TextBox textBox1;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.ProgressBar progressBar1;
        private bool isProcessRunning;
    }
}

方案2: 利用线程池(Task.StartNew())

你只要把btnProcess_Click中的代码替换为下面的代码即可:

void btnProcess_Click(object sender, EventArgs e)
{
    if (isProcessRunning)
    {
        MessageBox.Show("A process is already running.");
        return;
    }
    Task<string[]>.Factory.StartNew(() => {
           isProcessRunning = true;
           return Directory.GetFiles(@"C:\", "*");
        })
        .ContinueWith(files => {
            string[] filesResult = files.Result;
            progressBar1.Maximum = filesResult.Length;
            Console.WriteLine("The Maximum of Progress Bar " + progressBar1.Maximum);
            return filesResult;
        })
        .ContinueWith(files => {
            string[] filesResult = files.Result;
            Console.WriteLine("The files count " + filesResult.Length);
            for (int n = 0; n < filesResult.Length; n++ )
            {
                // 模拟拷贝文件过程 
                Thread.Sleep(100);
                Console.WriteLine(filesResult[n]);
                progressBar1.Value = n + 1;
            }
        })
        .ContinueWith(files => {
            MessageBox.Show("Thread completed!");
            progressBar1.BeginInvoke(
                    new Action(() =>
                    {
                        progressBar1.Value = 0;
                    }
            ));
            isProcessRunning = false;
        });
}

当然,你也可以通过BackgroundWorker来做,可能更简单一点儿,原理相同,你可以搜索一下相关方案。

 

注意,我只是通过一个Thread.Sleep(100)来模拟你Copy文件的逻辑。

追问
BackgroundWorke这个怎么做呢?给个例子呗
百度网友bec1679
2014-07-03 · TA获得超过2185个赞
知道大有可为答主
回答量:1093
采纳率:66%
帮助的人:628万
展开全部
1. 先计算出文件总数量为 nMax
progressBar1.Maximum = nMax;
2. 复制完一个文件+1
progressBar1.Value++
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式