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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c#如何根据文件数量控制进度条相关的知识,希望对你有一定的参考价值。

c#根据文件的数量来控制进度条,也就是说,复制完一个文件,进度条前进一点,进度条的最大值是文件的数量

说实话,关于进度条的解决方案很多,我暂且假定你在做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这个怎么做呢?给个例子呗

参考技术A 1. 先计算出文件总数量为 nMax
progressBar1.Maximum = nMax;
2. 复制完一个文件+1
progressBar1.Value++

以上是关于c#如何根据文件数量控制进度条的主要内容,如果未能解决你的问题,请参考以下文章

CentOS7 查看当前打开文件数

如何限制上传的 dropzone.js 文件的数量?

C# WinForm自定义进度条

文件上传和进度条

可以在 C# 中打开的最大文件数是不是有限制?

C# 做一个播放音频文件的进度条该怎么实现呢??