Как реализовать быстрое фоновое обновление данных на форме 1С без зависания интерфейса?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При интеграции 1С с высоконагруженными внешними сервисами (биржами, системами телеметрии, трекерами заказов) разработчики часто сталкиваются с задачей отображения данных в режиме реального времени (например, каждые 1–2 секунды). Стандартная связка из фонового задания, записи в регистр сведений и вызова метода Элементы.ДинамическийСписок.Обновить() по таймеру через ПодключитьОбработчикОжидания() приводит к микрозависаниям интерфейса, дерганию скролла и блокировке действий пользователя. Разберем причины такого поведения платформы и рассмотрим эффективные варианты решения этой проблемы.

Выясним причины подвисания интерфейса

Проанализируем ключевые факторы, которые вызывают блокировку пользовательского интерфейса при частом обновлении данных:

  1. Файловый режим работы информационной базы. В файловой базе любая транзакция записи (даже в фоновом задании) блокирует всю таблицу или базу целиком. Когда на клиенте срабатывает чтение данных динамическим списком, запрос встает в очередь ожидания блокировки, что приводит к ощутимому зависанию клиентского приложения.
  2. Синхронность серверных вызовов динамического списка. Вызов метода Обновить() динамического списка инициирует синхронный контекстный вызов сервера. Клиентский поток платформы 1С однопоточен: на время выполнения запроса к СУБД, передачи выборки по сети и перерисовки таблицы интерфейс полностью замораживается и меняется курсор мыши.
  3. Избыточная транзакционная нагрузка. Постоянная запись тиков и стакана котировок каждые 2 секунды нагружает журнал транзакций и перестраивает индексы таблиц итогов регистра, снижая общую производительность СУБД.

Вариант 1. Замена динамического списка на Таблицу значений с точечным обновлением

Для небольших объемов данных (десятки или сотни строк) использование динамического списка избыточно. Гораздо эффективнее использовать реквизит формы типа ТаблицаЗначений. В этом случае мы исключаем тяжелые повторные инициализации списка платформой и обновляем только изменившиеся строки.

Посмотрим на базовую схему работы:

  1. При открытии формы загружаем начальные данные в реквизит формы ТаблицаКотировок.
  2. По таймеру через ПодключитьОбработчикОжидания() запрашиваем с сервера или внешнего источника только дельту (изменившиеся записи).
  3. Обходим массив изменений и обновляем строки таблицы формы по ключевому полю (например, коду валютной пары) через метод НайтиСтроки().

&НаКлиенте
Процедура ОбработчикОбновления() Экспорт
    // Получаем массив только изменившихся данных
    МассивИзменений = ПолучитьОбновленияНаСервере();
    
    Для Каждого СтрДанных Из МассивИзменений Цикл
        Отбор = Новый Структура("ВалютнаяПара", СтрДанных.ВалютнаяПара);
        НайденныеСтроки = ТаблицаКотировок.НайтиСтроки(Отбор);
        
        Если НайденныеСтроки.Количество() > 0 Тогда
            СтрокаТаблицы = НайденныеСтроки[0];
            СтрокаТаблицы.Цена = СтрДанных.Цена;
            СтрокаТаблицы.Объем = СтрДанных.Объем;
        Иначе
            НоваяСтрока = ТаблицаКотировок.Добавить();
            ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрДанных);
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

Вариант 2. Разделение потоков оперативного отображения и долговременного учета

Рассмотрим архитектурное разделение: высокочастотные данные для оперативной работы пользователя не обязательно сразу сохранять в базу данных 1С. Объект HTTPСоединение доступен на клиенте, что позволяет открытой форме получать поток котировок напрямую с API биржи без транзакционной нагрузки на информационную базу.

  1. Клиентский контур формы: Форма самостоятельно делает быстрые легковесные HTTP-запросы (или читает входящие события) и сразу отображает котировки в интерфейсе.
  2. Серверный контур базы: В базу данных сохраняются только агрегированные показатели (например, свечи за минуту/час) либо совершенные пользователем операции и выставленные ордера.

Вариант 3. Использование поля HTML-документа и WebSocket

Если требуется непрерывный поток данных высокой частоты (несколько обновлений в секунду) с мгновенной перерисовкой без участия серверного контекста 1С, наиболее производительным решением является вывод интерфейса через ПолеHTMLДокумента.

Разберем по шагам, как устроена такая схема:

  1. В форму встраивается элемент управления ПолеHTMLДокумента.
  2. Внутри загружаемого HTML-документа запускается JavaScript-скрипт, который подключается по протоколу WebSocket к внешнему сервису.
  3. Отрисовка котировок и стакана заявок выполняется средствами браузерного движка (Virtual DOM, легкие CSS-сетки) с частотой 60 кадров в секунду, полностью изолированно от основного потока 1С.
  4. Для отправки торговых приказов по клику на строку таблицы в JavaScript формируется навигационное событие или обратный вызов, который перехватывается платформой 1С через событие поля HTML или метод оповещения формы.

Вариант 4. Перевод базы в клиент-серверный режим

Если от динамических списков и хранения в регистре отказаться невозможно, обязательным шагом является перевод базы с файлового режима на клиент-серверный вариант (MS SQL Server, PostgreSQL).

В современных СУБД механизм управления версиями строк (уровень изоляции Read Committed Snapshot Isolation в MS SQL или MVCC в PostgreSQL) гарантирует, что операции чтения динамического списка не блокируются фоновыми операциями записи данных в регистр сведений. Это позволяет практически полностью устранить долгие ожидания на блокировках таблиц.

← На главную