2010-03-24 8 views
17

L'application que j'écris effectue un algorithme de longueur qui prend habituellement quelques minutes pour terminer. Pendant ce temps, je voudrais montrer à l'utilisateur une barre de progression qui indique combien de l'algorithme est fait aussi précisément que possible.Modèles de conception de barre de progression?

L'algorithme est divisé en plusieurs étapes, chacune avec son propre timing typique. Par exemple-

    initialisation
  • (500 milli-secondes)
  • entrées de lecture (5 sec)
  • étape 1 (30 sec)
  • étape 2 (3 minutes)
  • sorties d'écriture (7 sec)
  • arrêt (10 milli-secondes)

Chaque étape peut signaler ses progrès assez facilement en réglant la r ange son travail sur, disons [0 à 150], puis en rapportant la valeur qu'il a complétée dans sa boucle principale.

Ce que j'ai actuellement mis en place est un schéma de moniteurs de progression imbriqués qui forment une sorte de rapport implicite d'arbre de progression.

Tous les moniteurs de progression hériteront d'une interface IProgressMonitor:

class IProgressMonitor 
{ 
public: 
    void setRange(int from, int to) = 0; 
    void setValue(int v) = 0; 
}; 

La racine de l'arbre est le ProgressMonitor qui est connecté à l'interface GUI réelle:

class GUIBarProgressMonitor : public IProgressMonitor 
{ 
    GUIBarProgressMonitor(ProgressBarWidget *); 
}; 

Tout autre nœud de l'arbre sont des moniteurs qui prennent le contrôle d'une partie de la progression du parent:

class SubProgressMonitor : public IProgressMonitor 
{ 
    SubProgressMonitor(IProgressMonitor *parent, int parentFrom, int parentLength) 
    ... 
}; 

Un SubProgressMonitor prend le contrôle de la plage [parentFrom, parentFrom+parentLength] de son parent.

Avec ce schéma, je suis capable de diviser statiquement la progression de niveau supérieur en fonction de la partie relative attendue de chaque étape de la temporisation globale. Chaque étape peut ensuite être subdivisée en plusieurs parties, etc. '

Le principal inconvénient de ceci est que la division est statique et qu'il est difficile d'effectuer des changements en fonction des variables découvertes au moment de l'exécution. Donc, la question: existe-t-il des modèles de conception connus pour la surveillance du progrès qui résolvent ce problème?

Répondre

1

Ceci est un problème difficile, nous avons déjà eu des difficultés avec un projet précédent. Le meilleur que je pourrais trouver est de recueillir des statistiques sur la durée réelle de chaque phase dans la vie réelle, et ajuster les longueurs d'intervalle relatives en conséquence.

Nous ne l'avons pas mis en œuvre dans ce projet si (au moins aussi longtemps que j'étais là-bas), donc c'est juste une idée théorique :-)

4

Péter WAS l'approche que je pris sur un grand projet; Au cours de notre déploiement pilote et initial, chacun de nos milliers d'appareils mobiles renvoyaient des données de synchronisation et d'utilisation, et nous avons utilisé les écarts moyens, médians et standard du temps pour affiner la configuration de nos tâches (lorsque le la tâche a été autorisée à s'exécuter, combien de temps il a été autorisé à s'exécuter, quelles valeurs ont été utilisées dans l'affichage de la barre de progression, etc.). Puisque notre solution a été construite un peu comme la vôtre mais pilotée par des valeurs fournies dans un fichier de configuration XML, nous avons pensé à la construire comme un système automatisé (par exemple, le serveur vérifie ces valeurs sur un certain intervalle jours qu'ils ont utilisé et mettre à jour le fichier de configuration pour les replanifier ou les rallonger), mais a supposé que cela ne valait pas la peine d'éviter un examen humain rapide toutes les quelques semaines. Comme je ne connais pas de solution technique à votre problème, je pense que ce que vous montrez à l'utilisateur (et combien de temps vous consacrez au développement d'une solution) devrait être basé sur des préoccupations fonctionnelles: qui l'utilise? Quelle est la précision de l'info? Est-ce un processus interactif au cours duquel ils ne peuvent faire aucun autre travail, ou peuvent-ils le laisser fonctionner en arrière-plan et y revenir? Est-ce que le processus de travail au cours de laquelle votre fonction de longue durée se produit est une tâche sensible au temps ou à la mission? Je suis désolé de ne pas pouvoir vous donner la réponse que vous cherchez, mais peut-être qu'en pensant à ce que vous essayez d'obtenir en gros coups, vous perdez une bonne idée. =)

5

Une approche très intéressante est la perception de l'utilisateur.

Chris Harrison a publié un document sur la façon dont l'utilisateur perçoit le passage du temps en fonction des progrès signalés par la barre de progression (bien que la durée réelle est évidemment identique dans toutes les expériences)

Notez que la formule d'affichage préféré est (x + (1-x)/2) où x est le progrès réel sur une échelle de 0 à 1 :)

par conséquent, je suggère:

  • se rassemblent quelques statistiques sur le pourcentage de temps qu'une tâche donnée prend
  • mesurez l'initialisation et utilisez-la pour mettre à l'échelle vos progrès sur la barre de progression, étant pessimiste (préparez un tampon de 10-15% par exemple)
  • juste avant la dernière tâche (ou quelques dernières tâches, tant qu'ils ont une durée déterministe), tout faire pour compléter la barre de progression dans le temps (avec accélération progressive)

Je sais, ce n'est pas précis, mais si les utilisateurs pensent c'est plus rapide je vais me contenter de ça!

0

Vous pouvez envisager de remplacer la barre de progression par un cercle de progression. Si la tâche a N étapes, alors faites N coins dans le secteur, et remplissez chaque coin comme une barre de progression, comme cette étape s'exécute. Comme une étape supplémentaire, peut-être avoir du texte affiché pour chaque étape, de sorte qu'ils ont quelque chose à lire pendant que l'étape progresse.

2

Construire un AggregateProgressMonitor qui calcule automatiquement les divisions de progression enfant en fonction des informations rapportées par les moniteurs de progression enfant.Le moniteur de progression de l'enfant doit au moins informer le parent du temps de fonctionnement "prévu". Les temps d'exécution estimés du moniteur enfant peuvent ensuite être mis à jour par leurs opérations respectives en fonction des paramètres d'exécution et le rapport d'avancement global sera ajusté en conséquence et automatiquement.

Quelque chose comme ça ...

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); 
    } 
}; 

Vous pouvez même utiliser le temps observé de la première étape à remapper les journalistes de progrès ultérieurs pour être plus précis.

Vous devrez conserver une carte ordonnée quelconque dans AggregateProgressMonitor pour pouvoir suivre et calculer toutes les informations provenant des enfants.

Une fois terminé, vous pouvez étendre AggregateProgressMonitor (en remplaçant les méthodes IProgressMonitor) pour afficher la progression à l'utilisateur.