2010-03-24 6 views
17

Приложение, которое я пишу, выполняет алгоритм длины, который обычно занимает несколько минут. За это время я хотел бы показать пользователю индикатор выполнения, который указывает, насколько алгоритм выполняется максимально точно.Шаблоны проектирования Progress Bar?

Алгоритм разделен на несколько этапов, каждый со своим собственным типичным временем. Для инициализации instance-

  • (500 милли-сек)
  • чтения входов (5 сек)
  • шаг 1 (30 сек)
  • шаг 2 (3 минуты)
  • пишущие выходы (7 сек)
  • выключая (10 милли-сек)

Каждый шаг может сообщить свой прогресс довольно легко, установив г ange работает, скажем [от 0 до 150], а затем сообщая о значении, которое оно завершило в своем основном цикле.

В настоящее время я настроил схему вложенных мониторов прогресса, которые образуют своего рода неявное дерево отчетов о прогрессе.

Все мониторы прогресса унаследован от интерфейса IProgressMonitor:

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

Корень дерева является ProgressMonitor, который связан с фактическим графическим интерфейсом:

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

Любой другой узел в дереве являются мониторами, которые контролируют кусок родительского хода:

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

A SubProgressMonitor получает контроль над диапазоном [parentFrom, parentFrom+parentLength] его родителя.

С помощью этой схемы я могу статически делить ход верхнего уровня в соответствии с ожидаемой относительной частью каждого шага в глобальном времени. Затем каждый шаг можно подразделить на куски и т. Д.

Основным недостатком этого является то, что разделение является статическим, и становится болезненным вносить изменения в соответствии с переменными, которые обнаруживаются во время выполнения.

Итак, вопрос: есть ли какие-либо известные шаблоны проектирования для мониторинга прогресса, которые решают эту проблему?

ответ

1

Это сложная проблема, мы также боролись с ней в предыдущем проекте.

Лучшее, что я мог придумать, это собрать статистику о том, как долго каждая фаза фактически выполняется в реальной жизни, и соответственно корректировать относительные интервалы.

Мы не реализовали в этом проекте, хотя (по крайней мере, до тех пор, как я был там), так что это просто теоретическая идея :-)

4

петровских был подход, который я взял на себя большой проект; во время нашего пилотного и первоначального развертывания каждое из наших тысяч мобильных устройств отправляло данные о сроках и использовании данных, и мы использовали средние, медианные и стандартные отклонения времени, затраченного на точную настройку наших задач (когда задача была разрешена для запуска, сколько времени было разрешено для запуска, какие значения использовались на дисплее индикатора выполнения и т. д.). Поскольку наше решение было построено немного как ваше, но оно управляется значениями, представленными в файле конфигурации XML, мы подумали о том, чтобы создать это как автоматизированную систему (например, сервер будет проверять эти значения на некоторый интервал, заметить, что некоторые задачи занимают больше времени в последних дней, которые они использовали, и обновить файл конфигурации, чтобы перенести или удлинить их), но полагал, что это не стоит хлопот, чтобы предотвратить быстрый обзор людей каждые несколько недель.

Поскольку я не знаю о техническом решении вашей проблемы, я думаю, что то, что вы показываете пользователю (и сколько времени вы тратите на разработку решения), должно основываться на функциональных проблемах: кто использует это? насколько точна информация? Является ли это интерактивным процессом, в ходе которого они не могут выполнять никакой другой работы или могут ли они работать в фоновом режиме и возвращаться к нему? Является ли процесс работы, в течение которого ваша долговременная функция выполняется с учетом времени или критически важная?

Прошу прощения за то, что я не могу дать вам ответ, который вы ищете, но, возможно, думать о том, чего вы пытаетесь добиться широкими ударами, дает отличную идею. =)

5

Очень интересный подход - восприятие пользователя.

Chris Harrison опубликовал статью о том, как пользователь воспринимает время прохождения в зависимости от хода сообщается индикатором выполнения (хотя фактическая продолжительность, очевидно, одинакова во всех экспериментах)

Обратите внимание, что предпочтительная формула дисплея (х + (1-х)/2) - где x является фактическим прогрессом в 0 до 1 шкалы :)

Поэтому я хотел бы предложить:

  • собирается некоторые статистические данные о проценте времени, которое требуется заданной задаче
  • измеряют инициализацию и используют ее для масштабирования вашего хода на индикаторе выполнения, будучи пессимистичным (например, подготовьте буфер 10-15%)
  • незадолго до последнего (или несколько последних задач, если они имеют детерминированную продолжительность), изо всех сил, чтобы завершить индикатор выполнения во времени (с прогрессивным ускорением)

Я знаю, это не точно, но если пользователи думают быстрее я соглашусь!

0

Возможно, вы захотите заменить индикатор выполнения с кругом хода. Если задача имеет N шагов, то сделайте N клинья в пироге и заполните каждый клин, как индикатор выполнения, по мере того, как этот шаг выполняется.

В качестве дополнительного шага, возможно, для каждого шага отображается некоторый текст, поэтому им нужно что-то читать, пока шаг прогрессирует.

2

Создайте 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), чтобы отобразить прогресс для пользователя.