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. 先计算出文件总数量为 nMaxprogressBar1.Maximum = nMax;
2. 复制完一个文件+1
progressBar1.Value++
以上是关于c#如何根据文件数量控制进度条的主要内容,如果未能解决你的问题,请参考以下文章