Шаблоны разработки Индикатора выполнения?

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

Алгоритм разделен на несколько шагов, каждого с его собственной типичной синхронизацией. Например,

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

Каждый шаг может сообщить о своем прогрессе довольно легко путем установки диапазона его работа над, сказать [от 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] из его родителя.

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

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

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

18
задан shoosh 24 March 2010 в 09:35
поделиться

5 ответов

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

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

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

1
ответ дан 30 November 2019 в 09:30
поделиться

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

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

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

4
ответ дан 30 November 2019 в 09:30
поделиться

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

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

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

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

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

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

5
ответ дан 30 November 2019 в 09:30
поделиться

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

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

-1
ответ дан 30 November 2019 в 09:30
поделиться

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

2
ответ дан 30 November 2019 в 09:30
поделиться