c#如何根据文件数量控制进度条
c#根据文件的数量来控制进度条,也就是说,复制完一个文件,进度条前进一点,进度条的最大值是文件的数量...
c#根据文件的数量来控制进度条,也就是说,复制完一个文件,进度条前进一点,进度条的最大值是文件的数量
展开
2个回答
展开全部
说实话,关于进度条的解决方案很多,我暂且假定你在做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这个怎么做呢?给个例子呗
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询