5

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

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

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

Я не хочу создавать несколько индикаторов выполнения. Вместо этого я хотел бы иметь единый индикатор прогресса, который информирует о глобальном прогрессе. На данный момент я могу думать о MVC и Observer/Observable, но это немного расплывчато :) Может быть, кто-то может указать мне в правильном направлении, спасибо.

ответ

1

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

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

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

1

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

6

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

У алгоритма было 6 различных шагов. На каждом шаге были временные характеристики, которые в значительной степени зависели от A) обрабатываемых базовых данных, а не только «количество» данных, но также «тип» данных и B) 2 шагов, очень хорошо масштабируемых с увеличением числа процессоров, 2 шага выполнялись в 2 потоках, а 2 этапа были эффективно однопоточными.

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

Решение, которое, наконец, сломало его, было действительно простым. Я сделал 6 функций, которые проанализировали набор данных и попытался предсказать фактическое время выполнения каждого этапа анализа. Эвристика в каждой функции анализировала как анализируемые наборы данных, так и количество процессоров. Основываясь на данных о времени выполнения на моем собственном 4-ядерном компьютере, каждая функция в основном возвращала количество миллисекунд, которое оно ожидало принять, на моей машине.

f1 (..) + f2 (..) + f3 (..) + F4 (..) + f5 (..) + f6 (..) = общее время выполнения в миллисекундах

теперь дано эту информацию, вы можете эффективно узнать, какой процент от общего времени выполнения каждого шага должен принимать. Теперь, если вы скажете, что шаг1 должен принимать 40% времени выполнения, вам в основном нужно выяснить, как испускать 40 1% событий из этого алгоритма.Скажем, для-цикл обработки 100000 элементов, вы могли бы, вероятно:

for (int i = 0; i < numItems; i++){ 
    if (i % (numItems/percentageOfTotalForThisStep) == 0) emitProgressEvent(); 
    .. do the actual processing .. 
} 

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

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

Теперь средний читатель SO может удивиться, почему на земле кто-то проведет неделю, делая гладкий индикатор прогресса. Эта функция была запрошена главным продавцом, и я считаю, что он использовал ее в торговых встречах для получения контрактов. Денежные переводы;)

+1

Приобретено для прохлады. – erikprice

2

В ситуациях с потоками или асинхронными процессами/задачами, подобными этому, я считаю полезным иметь абстрактный тип или объект в основном потоке, который представляет (и идеально инкапсулирует) каждый процесс. Таким образом, для каждого рабочего потока предположительно будет объект (давайте назовем его Operation) в основном потоке для управления этим рабочим, и, очевидно, для хранения этих операций будет какая-то структура данных в виде списка.

В каждом случае каждая Операция предоставляет методы старта/остановки для своего рабочего, а в некоторых случаях - например, ваши - числовые свойства, представляющие прогресс и ожидаемое общее время или работу этой задачи. Блоки не обязательно должны быть основаны на времени, если вы знаете, что будете выполнять 6 230 вычислений, вы можете просто подумать об этих свойствах как подсчету вычислений. Кроме того, каждая задача должна будет иметь некоторый способ обновления своей владения. Операция ее текущего прогресса в любом механизме является подходящей (обратные вызовы, закрытие, диспетчеризация событий или какой-либо механизм, который предоставляет ваш язык программирования/механизм потоковой передачи).

Таким образом, пока ваша фактическая работа выполняется в отдельных потоках, соответствующий объект операции в «основной» нити постоянно обновляется/уведомляется о прогрессе своего работника. Индикатор выполнения может обновить себя соответствующим образом, сопоставляя общее количество ожидаемых «Операций» с общей суммой, и общее количество «прогресса» Операций до его текущего прогресса, каким бы то ни было образом имеет смысл для вашей рамки показателей хода.

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