Почему «осталось 1 секунда» тянется так долго? — Как устроены индикатор выполнения и оценка оставшегося времени
· Обновлено: · Го Комура · Windows, индикатор выполнения, оставшееся время, UI, производительность
Вы смотрите на «осталось 1 секунда» уже 30 секунд. Только вы решили, что всё заканчивается, как надпись сменилась на «осталось 2 минуты».
Копирование файлов, установка приложения, экспорт видео. Индикатор выполнения удобен, но иногда кажется, что он живёт в другом мире, нежели часы.
На самом деле индикатор выполнения — не часы. Процент выполнения описывает, сколько работы уже сделано; оставшееся время показывает, сколько ещё, по всей видимости, предстоит; завершение означает, что нужные операции выполнились успешно. Если разделить эти три вещи, взгляд на ситуацию «99 %, а конца не видно» меняется.
В статье на примере документации по API и интерфейсам Windows объясняются общие механизмы. Это не разбор внутреннего алгоритма какой-либо конкретной версии проводника. Числовые примеры и демонстрация сравнения — вымышленная обработка для пояснения, а не измерения конкретного ПК или канала связи.
1. Сначала уточним, 100 % чего именно
Представьте, что вы просматриваете 100 документов. Если 99 из них — короткие заметки, а последний — толстый договор, утверждение «99 документов проверено» верно, но из него не следует, что «и 99 % времени позади».
В индикации прогресса смысл тоже зависит от того, что взято в знаменатель.
| Основа отсчёта | Что означает 50 % | Чего по одному этому числу не понять |
|---|---|---|
| Число файлов | Обработана половина целевых файлов | Размер оставшихся файлов и время их обработки |
| Объём данных | Обработана половина целевых байт | Дальнейшая скорость и этапы помимо передачи |
| Веса этапов | Пройдена половина заданного распределения | Совпадёт ли распределение с фактической длительностью этого запуска |
Например, обратный вызов прогресса, который используется в Windows у CopyFileEx, получает общий размер файла в байтах и число уже переданных байт. Это сведения об объёме работы, а не готовые секунды из будущего.1
flowchart TB
accTitle: Разница между процентом выполнения, оставшимся временем и завершением
accDescr: Схема разделяет отношение, вычисляемое по обработанному объёму, оценку времени на основе предположения о скорости и завершение, определяемое успешным результатом.
A["Обработанный и общий объём"] --> B["Процент выполнения"]
C["Оставшийся объём и прогнозируемая скорость"] --> D["Оценка оставшегося времени"]
E["Успех нужных операций"] --> F["Завершение всей работы"]
Рис. 1: Отношение, прогноз и результат — не три названия одной и той же информации.
В этой статье измеримую долю работы мы называем процентом выполнения, сам индикатор — индикатором выполнения, а прогноз в секундах — оценкой оставшегося времени. Даже когда оценку построить не удаётся, уже измеренный прогресс от этого не пропадает.
На схеме сплошная линия обозначает отношение, которое выполняется всегда, а пунктирная — условное отношение (условия указаны в пояснении к каждому отношению на странице сведений). Полный список отношений (всего 9, с доказательствами и степенью уверенности) и определения основных понятий собраны на странице сведений карты знаний (на японском). Данные: JSON-LD / Turtle
2. Как «осталось 10 секунд» превращается в «осталось 79 секунд»
Самая простая оценка оставшегося времени выглядит так.
Оставшееся время ≈ оставшийся объём работы ÷ оценка дальнейшей скорости обработки
Сложность не в делении, а в том, что будущую скорость пока невозможно наблюдать. Поэтому её прогнозируют по прошлой скорости. Реймонд Чен из Microsoft в разборе 2004 года о времени копирования тоже описал эту трудность предсказания будущего. Это не спецификация того, как Windows считает сейчас.2
Рассмотрим вымышленное копирование объёмом 1 000 MiB. Здесь MiB — это 1 048 576 байт. Пусть сначала оно идёт с постоянной скоростью 80 MiB/s в течение 2,5 секунды, а затем на следующую секунду скорость снижается до 10 MiB/s.
| Момент наблюдения | Передано | Осталось | Скорость для оценки | Оставшееся время |
|---|---|---|---|---|
| 2,5 секунды после начала | 200 MiB | 800 MiB | 80 MiB/s | 800 ÷ 80 = 10 секунд |
| 3,5 секунды после начала | 210 MiB | 790 MiB | 10 MiB/s | 790 ÷ 10 = 79 секунд |
За эту секунду работа продвинулась. И всё же прогноз скорости для оставшейся работы упал в восемь раз, поэтому оценка стала больше. В этом примере скорость последнего интервала наблюдения берётся как есть.
flowchart TB
accTitle: Почему оставшееся время растёт, хотя работа продвигается
accDescr: Если прогнозируемая скорость падает достаточно сильно, её влияние перевешивает уменьшение оставшегося объёма, и рассчитанное оставшееся время растёт.
A["За секунду пройдено 10 MiB"] --> B["Оставшийся объём уменьшается"]
C["Прогноз скорости резко падает"] --> D["Оставшееся время может вырасти"]
B --> D
Рис. 2: Рост оценки оставшегося времени — не то же самое, что возврат обработки назад.
С «осталось 1 секунда» всё так же. Объём, на который при прошлой скорости ушла бы одна секунда, не уложится в неё, если следующая операция окажется медленнее. На индикацию влияют и интервалы наблюдения, и способ округления секунд. Но если число не меняется бесконечно, не стоит считать это нормой: нужно, как описано ниже, различать этапы работы, обновление экрана и настоящую остановку.
3. Станет ли оценка точнее, если брать среднее?
Если отражать в индикаторе каждое мгновенное изменение скорости, число будет постоянно прыгать. Если же использовать только среднее с самого начала, влияние быстрого старта сохранится, и оценка долго не сможет догнать последующее устойчивое замедление.
Эта разница объясняется способом смешивания наблюдений. Если смешать прошлую скорость 80 и новейшую 10 пополам, прогнозируемая скорость составит 45. Оценка будет плавнее, чем при использовании только значения 10, но если скорость действительно останется равной 10, какое-то время она будет слишком оптимистичной. Плавность и реакция на изменения — разные цели.
flowchart TB
accTitle: Компромисс при сглаживании скорости
accDescr: Больший вес последнего наблюдения делает оценку чувствительной к изменениям, но колеблющейся, а больший вес прошлого — плавной, но с запаздыванием.
A["Наблюдения скорости"] --> B["Больший вес последнего значения"]
A --> C["Больший вес прошлого"]
B --> D["Чувствительно, но с колебаниями"]
C --> E["Плавно, но с запаздыванием"]
Рис. 3: Спокойный вид числа и точность прогноза — не одно и то же.
Это пример для размышления о способах прогнозирования, а не описание реализации конкретного продукта. Предложение по проектированию в этой статье такое: сразу после запуска или после смены этапа не надо навязчиво выводить секунды, а когда наблюдений накопится достаточно, показывать оценку вида «около минуты». Сказать, что оставшееся время пересчитывается, меньше вводит в заблуждение, чем поддерживать ничем не обоснованное «осталось 1 секунда».
4. 99 файлов готово, а по объёму данных — 9,9 %
Теперь речь не о скорости, а о единице измерения. Пусть есть 100 файлов: первые 99 по 1 MiB каждый, а последний — 901 MiB. В сумме получается 1 000 MiB.
Когда первые 99 файлов готовы, по числу файлов выходит 99 ÷ 100 = 99 %. Но по объёму данных — 99 ÷ 1 000 = 9,9 %. Остался всего один файл, но в нём 90,1 % данных. Оба расчёта верны, просто они считают разное.
flowchart TB
accTitle: Когда последний файл большой
accDescr: Если после 99 маленьких файлов остаётся большой файл, прогресс по числу файлов и прогресс по объёму данных сильно расходятся.
A["99 маленьких файлов"] --> B["По числу файлов почти готово"]
C["Последним остался большой файл"] --> D["Объёма данных осталось много"]
B --> E["Одна и та же работа, разные индикаторы"]
D --> E
Рис. 4: 99 % по числу файлов не обещают, что обработки осталось 1 %.
Значит, достаточно смотреть только на байты? Тоже нет. При передаче множества маленьких файлов по SMB снова и снова возникают затраты на создание файлов и на обмен запросами. При том же суммарном числе байт, что и у одного большого файла, время получится другим.3
Поэтому даже если измерение «осталось 500 MiB» верное, при другом составе этих 500 MiB затрачиваемое время может измениться. Показывать и число файлов, и число байт стоит не потому, что одно из них ошибочно, а потому, что каждое дополняет то, чего не видно в другом.
5. Долгое «Подготовка» — иногда это поиск знаменателя
Чтобы получить долю, нужен общий объём, то есть знаменатель. Однако в момент, когда приложению велено «обработать всю папку», оно не обязательно уже перечислило все файлы внутри неё.
Допустим, приложение считало, что элементов 100, обработало 80, а потом нашло ещё 100. Тогда те же 80 элементов вместо 80/100 дают 80/200. Индикатор падает с 80 % до 40 %, но выполненная работа никуда не исчезла. Расхождение с ожиданиями читателя создаёт именно показ ещё не определённого общего объёма как окончательного.
flowchart TB
accTitle: Индикация на этапе, когда общий объём ещё неизвестен
accDescr: Пока цели ещё выясняются, долю не фиксируют, а когда общий объём известен, его вместе с обработанным объёмом показывают как процент выполнения.
A["Выяснение целей"] --> B{"Общий объём известен?"}
B -->|"Ещё нет"| C["Показать этап и число найденных элементов"]
B -->|"Известен"| D["Показать долю"]
Рис. 5: Состояние без знаменателя и состояние с прогрессом 0 % — разные вещи.
У элементов прогресса Windows тоже есть и индикация с известным значением, и индикация, показывающая активность, пока значение неизвестно.4 В этой статье для такого случая рекомендуется во время перечисления показывать «Проверка целей: найдено 1 200 элементов», а долю выводить только после того, как общий объём определён. Отсутствие числа секунд само по себе не доказывает, что ничего не происходит.
6. «Передача 100 %» и «всё завершено» — разные границы
6.1 В конце иногда остаётся другая работа
Для пояснения разделим работу приложения на три этапа: передача → проверка → фиксация результата. Если по проекту после передачи нужно проверить переданное, работа целиком на этом не заканчивается. Это пример проекта одного приложения, а не утверждение, что всякое копирование или установка идут именно в таком порядке.
flowchart TB
accTitle: Завершение передачи и завершение всей работы
accDescr: В этом вымышленном приложении после передачи выполняются проверка и фиксация результата, поэтому по одному лишь числу переданных байт нельзя судить об успехе всей работы.
A["Передача"] --> B["Проверка"] --> C["Фиксация результата"] --> D["Общий успех"]
A -.-> E["Передача 100 % заканчивается здесь"]
Рис. 6: Если явно указать, что именно завершено, можно объяснить и наличие этапа после 100 %.
Здесь последовательнее, вместо того чтобы держать общий индикатор на 99 % с надписью «осталось 1 секунда», переключить состояние на «Передача завершена, идёт проверка». Руководство Microsoft по интерфейсу рабочего стола также требует не показывать завершение всей работы до того, как она действительно закончится.5
6.2 У записи тоже не одна граница
В Windows при записи в файл обычно используется кэширование. Граница между тем, что записало приложение, и тем, что дошло до носителя, зависит от настроек и условий API.6 FlushFileBuffers — это API, который отправляет буферизованные данные указанного файла на устройство.7
flowchart TB
accTitle: Концептуальная схема записи через буфер
accDescr: При использовании буфера запись, принятую от приложения, и её попадание на носитель не следует считать одним и тем же событием.
A["Запись из приложения"] --> B["Хранение в буфере"] --> C["Запись на носитель"]
Рис. 7: Это концептуальная схема записи через буфер, а не условия завершения конкретного продукта.
Однако нельзя утверждать, что остановка на 99 % всегда вызвана сбросом кэша. Проверка, сброс или другое ожидание — что именно происходит, нужно выяснять по проекту приложения и его записям. По числу прогресса не стоит догадываться даже о том, можно ли вынимать USB-накопитель или отключать питание.
7. Работа действительно остановилась или остановился только индикатор?
В приложениях WPF в Windows работой экрана занимается Dispatcher потока UI. Если надолго занять этот поток, обновление экрана и реакция на ввод задерживаются. Нужно отдельно рассматривать фоновую обработку и ту обработку, которая выводит её результат на экран.8
flowchart TB
accTitle: Путь от обработки до индикатора прогресса
accDescr: Даже если обработка сообщает о прогрессе, без обработки обновления на стороне UI он не появится на экране.
A["Собственно обработка"] --> B["Сообщение о прогрессе"] --> C["Обработка обновления на стороне UI"] --> D["Вывод на экран"]
E["Блокировка потока UI"] -.-> C
Рис. 8: Остановка индикатора не обязательно означает остановку самой обработки.
Наоборот, если анимация спроектирована так, что работает независимо от реальной обработки, круглая анимация может вращаться и тогда, когда работа ждёт. Выбора «двигается, значит всё в порядке» и «не двигается, значит поломка» здесь недостаточно.
| Что наблюдать | Какой признак это даёт | Чего по нему одному утверждать нельзя |
|---|---|---|
| Изменение числа или объёма обработанного и названия этапа | Сообщаемое продвижение работы | Завершится ли вся работа успешно |
| Время, объекты и ошибки в журнале | Что и где было записано как произошедшее | Остановилась ли работа, которая не пишет в журнал |
| ЦП, диск и сеть у нужного процесса | Использование ресурсов в этот момент | Нормальное продвижение, ожидание или бесполезный повтор |
| Окно подтверждения в отдельном окне | Ожидание действия пользователя | Все причины остановки |
Порядок, который рекомендуется в этой статье: сначала зафиксировать экран и время начала, проверить, нет ли окна, ожидающего подтверждения, и сравнить, меняются ли число элементов и записи в журнале. Показания диспетчера задач оставляем лишь вспомогательным свидетельством. Если рассматривается принудительное завершение, проверьте, как это приложение отменяет работу и что происходит с промежуточными результатами.
Отмена в .NET тоже устроена не так, что запрос немедленно останавливает обработку: это согласованный механизм, при котором сторона обработки откликается на запрос.9 Отсюда же и причина различать «отмена выполняется» и «отменено». Универсального числа «через сколько минут можно принудительно завершать» по одному этому индикатору не вывести.
8. Сравним одну и ту же работу на трёх индикаторах
Открыть демонстрацию сравнения индикаторов выполнения
В этой демонстрации кнопка продвигает момент наблюдения вымышленной обработки. Ждать не нужно, файлы не читаются, не записываются и не выгружаются. Первый случай — «99 маленьких файлов и один большой файл». Для одного и того же момента рядом показаны индикатор по числу файлов, индикатор по объёму передачи и состояние всей работы.
Пока передаётся последний большой файл, индикатор по числу файлов стоит на 99 %, а индикатор по объёму передачи растёт. Когда объём передачи достигает 100 %, общее состояние всё ещё «идёт проверка». И только следующий момент даёт успех. Так можно убедиться, что только из-за различия в отображении одна и та же работа может выглядеть и остановившейся, и продвигающейся.
flowchart TB
accTitle: Как читать демонстрацию сравнения
accDescr: Наблюдения одной и той же вымышленной обработки передаются в три индикатора: число файлов, объём передачи и общее состояние.
A["Одна вымышленная обработка"] --> B["Один и тот же момент наблюдения"]
B --> C["Доля по числу файлов"]
B --> D["Доля по объёму передачи"]
B --> E["Состояние всей работы"]
Рис. 9: Демонстрация сравнивает три способа показа одной работы, а не три разные работы.
В другом случае воспроизводится замедление из раздела 2 и показывается расчёт, в котором 10 секунд превращаются в 79. Используется такой расчёт. Это простая учебная оценка, а не реализация повторных попыток, параллельной обработки и прогноза по этапам, как в прикладном приложении.
function estimateSeconds(remaining, rate) {
if (!Number.isFinite(remaining) || remaining < 0) return null;
if (remaining === 0) return 0;
if (!Number.isFinite(rate) || rate <= 0) return null;
const seconds = remaining / rate;
return Number.isFinite(seconds) ? seconds : null;
}
remaining и rate передаются в согласованных единицах, например MiB и MiB/s. Ноль здесь возвращается в значении «измеряемого объёма работы больше не осталось», а не «всё приложение успешно завершилось». Если оставшийся объём положителен, а скорость равна нулю или неизвестна, возвращается null, чтобы это не спутали с «осталось 0 секунд».
9. Цель разработчика — не выглядеть точным, а не вводить в заблуждение
В этой статье предлагается, чтобы в индикаторе прогресса текущий этап, измеренный объём работы, оставшееся время только при наличии обоснования и результат — успех, ошибка или отмена хранились отдельно. Даже когда доли этапов объединяются в один индикатор, распределение вида «передача 80 %, проверка 20 %» — это проектный вес, а не гарантия того, как распределится время на этот раз.
flowchart TB
accTitle: Сборка индикатора прогресса из наблюдений
accDescr: Текущий этап, измеренные величины, оценка оставшегося времени при наличии условий и итоговый результат показываются раздельно.
A["Сведения, полученные от обработки"] --> B["Текущий этап"]
A --> C["Измеренный и общий объём"]
A --> D["Оценка при выполнении условий"]
A --> E["Успех, ошибка или отмена"]
Рис. 10: Наблюдаемое и предсказанное различаются и на экране.
Например, надпись «Проверка: 400 / 1 000 элементов, оставшееся время вычисляется» полезна и без секунд. Если показывается время обновления, то «когда прогресс последний раз вырос» и «когда экран последний раз успешно связался» — тоже разные вещи. Проектировать нужно так, чтобы обновление только второго не создавало видимость нормального продвижения.
Тот же подход применим к доступности. HTML-элемент progress умеет обозначать неопределённое состояние, если опустить значение.10 В собственном ARIA-индикаторе прогресса при неизвестном значении тоже опускают aria-valuenow и задают имя, по которому понятно, что именно продвигается.11 Не только внешний вид, но и озвучиваемая информация должна честно отражать то, что известно.
10. Частые вопросы
Задача не заканчивается, хотя осталось 1 секунда, — это сбой?
По одной индикации решить нельзя. Отдельно проверяют промах оценки, другой этап, задержку обновления экрана и настоящую остановку. И оставлять всё как есть по принципу «так бывает, значит всё в порядке», и считать «прошло больше секунды, значит поломка» — поспешные выводы.
Если показано 99 %, значит оставшееся время — 1 % от всего?
Нет. И когда единица измерения доли — файлы, и когда байты, время на единицу не обязательно постоянно. Умножить прошедшее время на 1 % и получить оставшееся время нельзя.
Если круглая анимация вращается, всё в порядке?
Индикация активности и свидетельство того, что обработка продвинулась, — разные вещи. Смотрят в сочетании: обработанный объём, этап, журнал. Одна анимация не гарантирует, что работа дойдёт до успешного завершения.
Если оставшееся время неизвестно, индикатор выполнения показать нельзя?
Если известны общий и обработанный объёмы, показать долю можно. Когда прогноз ненадёжен, опускают только секунды. Если неизвестен сам общий объём, используют неопределённый индикатор вместе с названием этапа и числом обработанных элементов.
11. Итог: оставшееся время — прогноз, завершение — результат
«Осталось 1 секунда» тянется долго не потому, что компьютер не умеет считать до одной секунды. Просто по уже наблюдённому объёму работы оценивается время обработки, которой ещё не было. Вдобавок накладываются единица измерения, поиск целей, последний этап и задержка обновления экрана.
flowchart TB
accTitle: Порядок чтения индикатора прогресса, который не заканчивается
accDescr: По очереди проверяют, какую долю показывает индикатор, изменился ли прогноз скорости, остался ли другой этап и что остановилось — индикатор или сама обработка.
A["Доля чего?"] --> B["Изменился ли прогноз скорости?"] --> C["Остался ли другой этап?"] --> D["Остановился индикатор или обработка?"]
Рис. 11: Разложим недовольство числом на вопросы, на которые можно ответить проверкой.
Пользователю стоит смотреть не только на числа, но и на этап и на изменения. Разработчику — не смешивать объём работы, прогноз и результат. Важнее, чем раз за разом угадывать «осталась одна секунда», объяснять, что происходит сейчас и что ещё неизвестно. В этом и состоит работа хорошего индикатора прогресса.
Справочные ссылки
-
Microsoft Learn, LPPROGRESS_ROUTINE callback function. Смысл числа байт, которое предоставляет обратный вызов прогресса копирования. ↩
-
Microsoft, The Old New Thing, Why does the copy dialog give such horrible estimates?. Разбор 2004 года. Приводится не как спецификация внутренней реализации нынешней Windows, а как объяснение трудности прогноза будущей скорости. ↩
-
Microsoft Learn, Slow SMB files transfer speed. Повторяющиеся затраты на создание файлов и на обмен данными при передаче маленьких файлов. ↩
-
Microsoft Learn, Progress controls. Элементы управления для случаев, когда прогресс можно определить и когда он неизвестен. ↩
-
Microsoft Learn, Progress Bars. Руководство по проектированию индикации прогресса в приложениях рабочего стола. ↩
-
Microsoft Learn, File Caching. Кэширование файлов и обработка записи. ↩
-
Microsoft Learn, FlushFileBuffers function. API, который отправляет буферизованные данные файла на устройство. ↩
-
Microsoft Learn, Threading model. Dispatcher в WPF и отзывчивость потока UI. ↩
-
Microsoft Learn, Cancellation in Managed Threads. Согласованная отмена в .NET. ↩
-
WHATWG, The progress element. Элемент прогресса в HTML и неопределённое состояние. ↩
-
W3C, WAI-ARIA 1.2: progressbar. Правила имени и значения для озвучиваемой информации о прогрессе. ↩
Похожие статьи
Недавние статьи с теми же тегами помогут подробнее изучить близкие темы.
Высокий DPI в WPF — почему «к DPI должен быть готов», а на деле всё размывается
WPF по умолчанию System DPI Aware, но при переносе окна на монитор с другим DPI всё изображение размывается, а растр теряет резкость. Раз...
Поддержка высокого DPI в WinForms — почему на 4K размывается или ломается макет
Разбираем, почему WinForms-приложение на 4K-мониторе размывается или ломается: виртуализация DPI и режимы осведомлённости о DPI (System A...
Как ярлык Windows находит перемещённый файл? — Местоположение файла и его идентичность — разные вещи
Почему ярлык по-прежнему открывает перемещённый файл? Windows ищет цель не только по сохранённому пути, но и по идентификаторам отслежива...
Нужно ли по-прежнему «безопасно извлекать» USB-накопитель? — взгляд через быстрое удаление и кэш записи
Копирование закончилось — можно ли сразу вынуть USB-накопитель? Разбираем кэш записи и разницу между «быстрым удалением» и «повышенной пр...
Почему звук прерывается при низкой загрузке CPU? — взгляд от буфера и сроков
Звук прерывается щелчками, хотя загрузка CPU низкая. Объясняем причину через буфер, в котором звук накапливается немного вперёд, и срок п...
Связанные темы
Эти страницы показывают тему статьи в более широком контексте услуг и решений.
Технические темы Windows
Раздел о разработке Windows, расследовании сбоев и использовании существующих активов.
Поток UI и таймеры
Поток UI WPF / WinForms, асинхронные операции, Dispatcher и проектирование таймеров.
Услуги по этой теме
Статья напрямую связана со следующими услугами.
Разработка приложений для Windows
Бизнес-приложения, интеграция оборудования и средства связи — от требований до разработки.
Частые вопросы
Вопросы, которые часто возникают при консультациях по теме статьи.
- Задача давно стоит на «осталось 1 секунда» — это неисправность?
- По одной только индикации судить нельзя. Отдельно проверяют промах в оценке скорости, последний этап, не обновляющийся экран и настоящую остановку. Посмотрите, меняются ли число обработанных элементов и записи в журнале, нет ли окна, ожидающего подтверждения, и не завершайте процесс принудительно только из-за числа «осталось 1 секунда».
- Если показано 99 %, значит и оставшееся время — 1 % от общего?
- Нет. Смысл зависит от того, что именно выражают эти 99 % — число элементов, объём данных или этапы работы, — и время на каждую такую единицу не обязательно одинаково. Процент выполнения — это доля работы, а не само оставшееся время.
- Если круглая анимация вращается, значит обработка идёт нормально?
- Это не доказательство того, что обработка продвигается. Там, где анимация и обработка работают независимо друг от друга, анимация может вращаться и во время ожидания. Отличайте её от признаков выполненной работы: числа элементов, смены этапов, записей в журнале.
- Если точное оставшееся время неизвестно, то и индикатор выполнения показать нельзя?
- Можно. Когда общий и обработанный объёмы известны, можно показать их отношение, а при нестабильной скорости предусмотреть вариант, в котором оставшееся время просто не выводится. Если неизвестен сам общий объём, показывают неопределённое состояние вместе с названием этапа и числом обработанных элементов, а не выдуманный процент.
Об авторе
Страница с профилем автора статьи.
Го Комура
Представитель KomuraSoft LLC
Специализируется на разработке программного обеспечения для Windows, техническом консалтинге и расследовании сбоев, особенно в проектах с унаследованными системами и трудно воспроизводимыми ошибками.