正确使用进度条
Posted
技术标签:
【中文标题】正确使用进度条【英文标题】:Proper use of progress bar 【发布时间】:2016-08-14 07:16:53 【问题描述】:这是我第一次在 C# 中使用进度条。 我的代码正在复制一些文件,我想通过进度条显示进度。
我不喜欢我的代码的一点是,我必须通过所有文件来设置栏的最大值……然后我再次通过相同的过程来复制文件。
如果不这样做,我就是想不出一种方法来确保在酒吧中顺利进行。我首先必须知道最大值对吗?还是有什么诀窍?
代码如下:
设置最大值:
private static void setProgressBar(List<Source> sources, List<Destination> destinations)
progress.Value = 0;
progress.Maximum = 0;
foreach (var source in sources)
progress.Maximum += System.IO.Directory.GetDirectories(source.directory, "*",
SearchOption.AllDirectories).Count() * destinations.Count +
System.IO.Directory.GetFiles(source.directory, "*.*", SearchOption.AllDirectories).Count() *
destinations.Count;
复制文件:
public static void CopyData(List<Source> sources, List<Destination> destinations, RichTextBox box, ProgressBar bar)
log = box;
progress = bar;
setProgressBar(sources, destinations);
foreach (var source in sources)
foreach (var dirPath in System.IO.Directory.GetDirectories(source.directory, "*",
SearchOption.AllDirectories))
foreach (var destination in destinations)
logger(dirPath);
System.IO.Directory.CreateDirectory(dirPath.Replace(source.directory, destination.directory));
foreach (var newPath in System.IO.Directory.GetFiles(source.directory, "*.*", SearchOption.AllDirectories))
foreach (var destination in destinations)
logger(newPath);
File.Copy(newPath, newPath.Replace(source.directory, destination.directory), true);
增加进度条:
私有静态无效记录器(字符串输出) log.Text += "复制:" + 输出 + System.Environment.NewLine; log.SelectionStart = log.Text.Length; log.ScrollToCaret(); 进度.增量(1);
所以我两次运行相同的代码......我不喜欢这样:)
【问题讨论】:
【参考方案1】:我在这里看到两个错误:您从未在 CopyData 方法中设置进度条的值 第二个是:您的 CopyData 方法将导致您的 UI 冻结,直到该方法完成(此时进度条将从 0 跳转到 100%)。
您可以将 CopyData 方法放在 BackgroundWorker 中并调用 ReportProgress 并在 ReportProgress 事件中设置栏的新值。
这是一个如何完成的示例。而不是static void Main(..)
调用工作人员,您将从那里开始您的 CopyData 方法
static void Main(string[] args)
System.ComponentModel.BackgroundWorker worker = new System.ComponentModel.BackgroundWorker();
worker.ProgressChanged += Worker_ProgressChanged;
worker.DoWork += Worker_DoWork;
//Do work
worker.RunWorkerAsync();
private static void Worker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
//Get Values
var source = null;
var destinations = null;
//CopyData Method
setProgressBar(sources, destinations);
foreach (var source in sources)
foreach (var dirPath in System.IO.Directory.GetDirectories(source.directory, "*", SearchOption.AllDirectories))
foreach (var destination in destinations)
logger(dirPath);
System.IO.Directory.CreateDirectory(dirPath.Replace(source.directory, destination.directory));
//Increase Value by 1
(sender as System.ComponentModel.BackgroundWorker).ReportProgress(1);
foreach (var newPath in System.IO.Directory.GetFiles(source.directory, "*.*", SearchOption.AllDirectories))
foreach (var destination in destinations)
logger(newPath);
File.Copy(newPath, newPath.Replace(source.directory, destination.directory), true);
//Increase Value by 1
(sender as System.ComponentModel.BackgroundWorker).ReportProgress(1);
private static void Worker_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
if (e.ProgressPercentage == 1)
//If Value gets higher than Maximum it will cause an Exception
if (progress.Value < progress.Maximum)
progress.Value += 1;
private static void setProgressBar(List sources, List destinations)
progress.Value = 0;
progress.Maximum = 0;
foreach (var source in sources)
foreach (var dirPath in System.IO.Directory.GetDirectories(source.directory, "*", SearchOption.AllDirectories))
//Simplified
progress.Maximum += destinations.Count;
foreach (var newPath in System.IO.Directory.GetFiles(source.directory, "*.*", SearchOption.AllDirectories))
//Simplified
progress.Maximum += destinations.Count;
【讨论】:
感谢您的回复,首先缺少一个方法,因此您看不到我确实在logger(newPath)
方法中增加了进度条的值。所以它不会从 0 跳到 100。其次,通过 BackgroundWorker 执行此操作并不能改善性能最密集的代码(您简化的代码)运行两次的情况!想象一下,有 2000 个目录,程序会减慢 1.5。 - 2次。我正在寻找一种方法来改善它。不知道有没有可能
我又读了几篇关于后台工作人员的文章,发现它们在不同的线程中运行。所以我认为你的回答对我有帮助!
很高兴听到 :) 关于性能密集型代码的另一个问题。您可以忽略直到您写入文件的目录并检查目标文件的目录是否存在。如果没有 -> 创建它。到目前为止,这将是我对这部分问题的唯一想法。以上是关于正确使用进度条的主要内容,如果未能解决你的问题,请参考以下文章