我编写的应用程序执行一个长度算法,通常需要几分钟才能完成。在这段时间里,我想向用户展示一个进度条,它尽可能精确地表示算法完成了多少。
该算法分为几个步骤,每个步骤都有自己的典型定时。例如-
每个步骤都可以很容易地报告它的进度,方法是设置它的工作范围,比如0到150,然后报告它在主循环中完成的值。
我目前设置的是一个嵌套进度监视器方案,它形成了一种隐式进度报告树。
所有进度监视器都是从接口IProgressMonitor继承的。
class IProgressMonitor
{
public:
void setRange(int from, int to) = 0;
void setValue(int v) = 0;
};树的根是ProgressMonitor,它连接到实际的GUI界面:
class GUIBarProgressMonitor : public IProgressMonitor
{
GUIBarProgressMonitor(ProgressBarWidget *);
};树中的任何其他节点都是监控器,它们控制父进程的一部分:
class SubProgressMonitor : public IProgressMonitor
{
SubProgressMonitor(IProgressMonitor *parent, int parentFrom, int parentLength)
...
};SubProgressMonitor控制其父级的范围[parentFrom, parentFrom+parentLength]。
有了这个方案,我就能够根据全局定时中每一步的预期相对部分,静态地划分最高级别的进度。然后,每一步都可以进一步细分为几个部分。
它的主要缺点是,除法是静态的,根据在运行时发现的变量进行更改会很痛苦。
那么问题是:是否有任何已知的设计模式可以解决这个问题?
发布于 2010-03-24 15:28:52
Péter's是我在一个大型项目上采用的方法;在我们的试点和初步推出过程中,我们成千上万的移动设备都在发送时间和使用数据,我们使用了用于微调任务配置所需时间的平均、中位数和标准差(任务允许运行的时间、允许运行多长时间、在进度条显示中使用了什么值等)。由于我们的解决方案构建得有点像您的解决方案,但由XML配置文件中提供的值驱动,所以我们考虑将其构建为一个自动化系统(例如,服务器会在某个时间间隔检查这些值,注意到最近几天某些任务比以前花费的时间更长,并更新配置文件以重新安排或延长配置文件),但我们认为这不值得仅仅为了防止每隔几周就进行一次快速的人工检查。
由于我不知道您的问题的技术解决方案,我认为您向用户展示的内容(以及您开发解决方案所花费的时间)应该基于功能方面的考虑:是谁在使用这个解决方案?信息需要有多准确?这是一个互动的过程,在这个过程中,他们不能做其他的工作,或者他们可以让它在后台运行并返回到它?您长期运行的功能发生的工作过程是时间敏感的还是任务关键的?
很抱歉,我不能给你你想要的答案,但也许思考一下你想在泛泛的笔划中实现什么,这是个好主意。=)
发布于 2010-05-18 21:53:43
生成一个AggregateProgressMonitor,它根据子进度监视器报告的信息自动计算子进度分区。子进程监视器至少应该通知父进程“预期”运行时间。然后,可以根据运行时参数通过其各自的操作更新子监视器估计的运行时间,并将相应地自动调整总体进度报告。
就像这样..。
class IAggregateProgressMonitor : public IProgressMonitor
{
void setChildValue(IProgressMonitor *, int v);
void setChildEstimatedTime(IProgressMonitor *, int v);
}
class AggregateProgressMonitor : public IAggregateProgressMonitor
{
void setChildValue(IProgressMonitor * child, int v)
{
int aggregateValue = mapChildValueToAggregateValue(child, v);
setValue(aggregateValue);
}
void setChildEstimatedTime(IProgressMonitor * child, ulong ms)
{
children[child]->estimatedTime = ms;
updateChildProgressRatios();
}
}
class SubProgressMonitor : public IProgressMonitor
{
SubProgressMonitor(IAggregateProgressMonitor *parent, int parentFrom,
int parentLength) ... ;
void setValue(int v)
{
parent->setChildValue(this, v);
}
void setEstimatedRunningTime(ulong ms)
{
parent->setChildEstimatedTime(this, ms);
}
};您甚至可以使用观察到的第一步的时间来重新映射后续的进度报告,以便更准确。
您需要在AggregateProgressMonitor中保存一张有序的地图,以便能够跟踪和计算来自孩子们的所有信息。
一旦完成,您可以扩展AggregateProgressMonitor (覆盖IProgressMonitor方法)以向用户显示进度。
发布于 2010-03-24 09:48:03
这是一个棘手的问题,我们在以前的一个项目中也与它作过斗争。
我能想出的最好办法是收集每个阶段在现实生活中实际需要多长时间的统计数据,并相应地调整相对间隔长度。
不过,我们还没有在那个项目中实现它(至少在我还在的时候),所以这只是一个理论上的想法:-)
https://stackoverflow.com/questions/2506550
复制相似问题