Мы сталкиваемся с интересным поведением платформы 1С:Предприятие, когда речь идет об асинхронных операциях и взаимодействии клиент-сервер. Многие из нас замечали, что в отчетах, реализованных с использованием Библиотеки стандартных подсистем (БСП), особенно при работе с длительными операциями в актуальных версиях подсистемы, при выполнении долгих операций в фоновом режиме, пользовательский интерфейс остается отзывчивым, и курсор мыши не меняет своего вида на характерное "колесико" (индикатор загрузки). Это происходит даже тогда, когда на клиенте подключен обработчик ожидания, который регулярно опрашивает сервер о статусе выполнения фонового задания.
Однако, когда мы пытаемся воспроизвести аналогичное поведение в своих разработках, например, вызывая простую серверную функцию через обработчик ожидания (подробнее о базовых принципах работы можно узнать в статье фоновые задания для новичков), курсор мыши начинает "дергаться", то есть каждый раз превращаться в индикатор загрузки. Это вызывает закономерный вопрос: почему БСП достигает такого "невидимого" взаимодействия с сервером, а наши собственные попытки приводят к видимому изменению курсора?
Давайте подробно разберем эту ситуацию, проанализируем механизмы платформы и выясним истинную причину такого поведения.
Автор отмечает, что в отчетах БСП, изучить механизмы которой поможет справочник по методам БСП с примерами, часто используется следующий сценарий:
ПодключитьОбработчикОжидания), который с определенной периодичностью (обычно раз в одну секунду) выполняет серверный вызов. Цель этого вызова — опросить текущий статус фонового задания и, при необходимости, получить его результат.Самое интересное заключается в том, что при таком опросе указатель мыши не делает характерного для серверного вызова превращения в колесико. Интерфейс остается полностью отзывчивым, и у пользователя не создается ощущения "подвисания" или ожидания.
Проблема возникает, когда автор пытается реализовать аналогичный механизм самостоятельно. Даже при вызове максимально простой серверной функции, курсор мыши все равно "дергается", меняя свой вид на индикатор загрузки при каждом серверном вызове. Это наводит на мысль о какой-то "хитрой" особенности БСП или платформы. Стоит отметить, что существуют способы реализовать фоновые задания и отслеживание результата без использования БСП, но и там разработчики сталкиваются с вопросами визуальной индикации.
Рассмотрим пример кода, который мог бы вызывать "дерганье" курсора в первоначальных экспериментах автора:
&НаКлиенте
Процедура ПриОткрытии(Отказ)
// Подключаем обработчик ожидания, который будет срабатывать раз в 1 секунду
ПодключитьОбработчикОжидания("ПроверкаДергатни", 1, Ложь);
КонецПроцедуры
// Серверная функция без явной директивы &НаСервереБезКонтекста
// По умолчанию, если ничего не указано, это будет контекстный вызов &НаСервере
&НаСервере
Функция ВремяКонтекстное()
Возврат ТекущаяДата();
КонецФункции
&НаКлиенте
Процедура ПроверкаДергатни()
// Вызываем серверную функцию для опроса
Перем ТекущееВремя;
ТекущееВремя = ВремяКонтекстное();
// Здесь обычно выполнялись бы действия по опросу результата фонового задания
// Но даже при таком простом вызове наблюдалось "дерганье" курсора
КонецПроцедуры
В этом сценарии, при каждом вызове функции ВремяКонтекстное(), которая является контекстным серверным вызовом, курсор мыши менялся на индикатор загрузки. Это противоречило поведению, наблюдаемому в типовых решениях.
&НаСервереБезКонтекстаПосле дальнейших экспериментов и анализа, автор нашел причину расхождений. Оказалось, что критическое значение имеет использование директивы компиляции &НаСервереБезКонтекста для серверной функции. Именно эта директива позволяет платформе оптимизировать клиент-серверное взаимодействие таким образом, чтобы избежать визуальной индикации занятости.
Рассмотрим пример, который в итоге продемонстрировал желаемое поведение (отсутствие "дерганья" курсора):
&НаКлиенте
Процедура ПриОткрытии(Отказ)
// Подключаем обработчик ожидания, который будет срабатывать раз в 1 секунду
ПодключитьОбработчикОжидания("ПроверкаДергатни", 1, Ложь);
КонецПроцедуры
// Серверная функция, помеченная директивой &НаСервереБезКонтекста
&НаСервереБезКонтекста
Функция Время()
// Простая и быстрая операция
Возврат ТекущаяДата();
КонецФункции
&НаКлиенте
Процедура ПроверкаДергатни()
// Вызываем серверную функцию без контекста
Перем ТекущееВремя;
ТекущееВремя = Время();
// Теперь курсор не "дергается"
КонецПроцедуры
В этом примере, вызов серверной функции Время(), помеченной как &НаСервереБезКонтекста, не приводит к изменению курсора на индикатор загрузки. Это особенно важно, если вы реализуете индикацию прогресса выполнения фонового задания самостоятельно, чтобы частые обновления прогресс-бара не раздражали пользователя мерцанием курсора.
&НаСервереБезКонтекста предотвращает "дерганье" курсора?Причина такого поведения кроется в глубоких механизмах оптимизации платформы 1С:Предприятие для работы с управляемыми формами и организации клиент-серверного взаимодействия. Рассмотрим ключевые факторы:
Когда клиент вызывает серверную процедуру или функцию, помеченную директивой &НаСервереБезКонтекста, платформа выполняет минимально необходимую передачу данных. Самое важное отличие заключается в том, что контекст формы не упаковывается и не передается на сервер. Исключение упаковки и передачи контекста значительно сокращает объем данных и ускоряет выполнение вызова. Для таких быстрых операций платформа целенаправленно не отображает индикатор загрузки, чтобы избежать мерцания интерфейса и сохранить высокую отзывчивость.
Метод ПодключитьОбработчикОжидания срабатывает при первой возможности, когда система "свободна". В сочетании с быстрым неконтекстным серверным вызовом платформа распознает это как неблокирующую операцию, не требующую визуальной индикации.
БСП строится на принципах минимизации клиент-серверного взаимодействия. В контексте опроса результатов фоновых заданий используются именно такие оптимизированные механизмы: легкие и быстрые вызовы без контекста. Это полностью согласуется с принципом асинхронности и "незаметности" для пользователя.
Отсутствие "дерганья" курсора обусловлено правильным применением директив компиляции. Если перед вами стоит задача выполнять частые серверные вызовы, не вызывая изменение курсора, следуйте этим рекомендациям:
&НаСервереБезКонтекста: Для всех быстрых операций, не требующих данных формы, всегда применяйте эту директиву.
ПодключитьОбработчикОжидания для асинхронного опроса: Это стандартный и наиболее эффективный механизм для отслеживания статуса фоновых процессов.
Применяя эти подходы, мы можем создавать более производительные и удобные для пользователя интерфейсы в своих решениях на платформе 1С:Предприятие, следуя лучшим практикам, заложенным в Библиотеке стандартных подсистем.