1

假设我有一个按钮:btnExecute

此按钮执行所有这些方法:

doAction1();
doAction2();
doAction3();
doAction4();

这些操作中的每一个都需要几秒钟。

在运行这些方法中的每一个时,我将如何更新进度条?

我知道我可以进入它们中的每一个并添加 pbExecuteProgress.value = 10 例如,但我觉得必须有更好的方法来做到这一点。

我也不想做这样的事情:

doAction1();
pbExecuteProgress.value = 30
doAction2();
pbExecuteProgress.value = 60
doAction3();
pbExecuteProgress.value = 80
doAction4();
pbExecuteProgress.value = 100

有什么方法可以创建一个价值高达 100 的进度条并且 = 方法的进度?

4

3 回答 3

4

当您“嵌套”进度时,外部方法必须估计每个子例程执行所需的时间,并将其 100% 分配给子例程。

您可以任意执行此操作,即方法一为 40%,方法二为 25%,依此类推,或者您可以进行“试运行”来决定每种方法的工作量。例如,如果每个方法处理多个文件,试运行将计算文件而不实际处理它们,然后您可以使用每个方法的文件计数来分配适用于每个方法的进度条范围。

空运行方法给出了更准确的结果,但所需的预处理可能需要相当长的时间,从而使整个任务变慢。

一旦你有了每个子程序的范围,你就可以传递它们的开始和结束百分比,它们可以适当地推进进度。

处理此问题的一种巧妙方法是创建一个处理所有子任务缩放的进度管理器类,这使得嵌套调用的整个子树很容易,并且只在它们周围传递一个对象来处理进度显示。

于 2012-08-14T19:38:45.777 回答
4
var actions = new List<Action> {doAction1, doAction2, doAction3, doAction4};

foreach(var action in actions)
{
   action();
   progressBar.Value += (progressBar.Maximum - progressBar.Minimum) / actions.Count;
}

如果您想自定义进度值:

var actions = new Dictionary<Action, int> 
{
     {doAction1, 30}, 
     {doAction2, 30}, 
     {doAction3, 20}, 
     {doAction4, 20},
};

progressBar.Minimum = 0;
progressBar.Maximum = actions.Select(kvp=>kvp.Value).Sum();
progressBar.Value = 0;
foreach(var action in actions)
{
   action.Key();
   progressBar.Value += action.Value;
}

动作集合的声明和创建不必在循环之前发生。事实上,这种模式(策略模式的一种形式)的优势在于新的动作可以来自任何地方,包括当前类的内部和外部。

于 2012-08-14T19:51:33.133 回答
0

如果您真的想自己做,我建议对每个方法以及整个方法中的每个语句进行计时,将所有时间放入数组中,将它们转换为百分比,然后将 em 写入文本文件什么的。冲洗并重复,平均它们,然后你必须添加一堆pbExecuteProgress.value = X语句。我知道你说过你不想那样做,但至少这样可以非常准确地反映进展情况。

只是一个想法。

另外,我相当肯定有第三方工具可以为你做这种事情。但是,它们本质上不可能像上述方法一样准确。

于 2012-08-14T19:39:59.723 回答