Подтвердить что ты не робот

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

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

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

  • инициализация (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 *);
};

Любые другие node в дереве - это мониторы, которые управляют частью родительского хода:

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

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

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

Ответ 2

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

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

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

Ответ 3

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

Ответ 4

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

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

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

Ответ 5

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

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