Асинхронно скопировать часть пакета и обработать короткое чтение

Учебные задачи

Все байты собственные: 10/20/30/40/50. Из среза 20/30/40 копируем два байта, сокращаем до одного и читаем с отдельным смещением буфера.

Где и как запускать

Модуль пустой управляемой формы учебной внешней обработки; тонкий или толстый клиент Windows. Вставьте весь модуль. Это не серверный код.

Подготовка

  1. Создайте учебную внешнюю обработку с пустой управляемой основной формой. Создайте команду УчебныйПример и кнопку этой команды.

  2. В свойстве команды Действие выберите процедуру УчебныйПример. Вставьте полный приведённый модуль формы.

  3. Откройте EPF в тонком или толстом клиенте Windows и нажмите кнопку. Не переносите Ждать и Асинх в серверный общий модуль.

  4. Пример работает только со своими данными в памяти; записи в базу, файлы и сеть нет.

  5. Эти методы проверяются по установленной справке 8.5.1.1343, но фактический запуск в 1С здесь не подтверждён.

&НаКлиенте
Асинх Процедура УчебныйПример(Команда)
    Источник = Неопределено;
    Целевой = Неопределено;
    ОшибкаОперации = "";
    Попытка
        Источник = Новый ПотокВПамяти;
        Целевой = Новый ПотокВПамяти;
        ИсходныйБуфер = Новый БуферДвоичныхДанных(5);
        Для ИндексБайта = 0 По 4 Цикл
            ИсходныйБуфер.Установить(ИндексБайта, (ИндексБайта + 1) * 10);
        КонецЦикла;
        Ждать Источник.ЗаписатьАсинх(ИсходныйБуфер, 1, 3);
        Сообщить((Ждать Источник.РазмерАсинх()) = 3);
        Позиция = Ждать Источник.ПерейтиАсинх(0, ПозицияВПотоке.Начало);
        Сообщить(Позиция = 0);
        Скопировано = Ждать Источник.КопироватьВАсинх(Целевой, 2);
        Сообщить(Скопировано = 2);
        Сообщить((Ждать Целевой.РазмерАсинх()) = 2);
        Ждать Целевой.УстановитьРазмерАсинх(1);
        Ждать Целевой.СброситьБуферыАсинх();
        Сообщить((Ждать Целевой.РазмерАсинх()) = 1);
        Ждать Целевой.ПерейтиАсинх(0, ПозицияВПотоке.Начало);
        БуферЧтения = Новый БуферДвоичныхДанных(5);
        Для ИндексБайта = 0 По 4 Цикл
            БуферЧтения.Установить(ИндексБайта, 9);
        КонецЦикла;
        Прочитано = Ждать Целевой.ПрочитатьАсинх(БуферЧтения, 2, 3);
        Сообщить(Прочитано = 1);
        Сообщить(БуферЧтения.Получить(2) = 20);
        Сообщить(БуферЧтения.Получить(0) = 9);
        Сообщить(БуферЧтения.Получить(3) = 9);
    Исключение
        ОшибкаОперации = ОписаниеОшибки();
    КонецПопытки;
    ОшибкиЗакрытия = Ждать ЗакрытьСобственныеПотокиАсинх(Источник, Целевой);
    Если Не ПустаяСтрока(ОшибкаОперации) Или Не ПустаяСтрока(ОшибкиЗакрытия) Тогда
        ВызватьИсключение "Ошибка учебного потока: " + ОшибкаОперации + " " + ОшибкиЗакрытия;
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Асинх Функция ЗакрытьСобственныеПотокиАсинх(Первый, Второй)
    Ошибки = "";
    Если Первый <> Неопределено Тогда
        Попытка
            Ждать Первый.ЗакрытьАсинх();
        Исключение
            Ошибки = "Первый поток не закрыт: " + ОписаниеОшибки();
        КонецПопытки;
    КонецЕсли;
    Если Второй <> Неопределено Тогда
        Попытка
            Ждать Второй.ЗакрытьАсинх();
        Исключение
            Ошибки = Ошибки + " Второй поток не закрыт: " + ОписаниеОшибки();
        КонецПопытки;
    КонецЕсли;
    Возврат Ошибки;
КонецФункции

Разбор по шагам

  1. Каждый Асинх-метод возвращает Обещание. Ждать получает его результат и не допускает чтения ещё не завершённой записи.

  2. В ЗаписатьАсинх второй аргумент — позиция в исходном буфере, а не позиция потока. Из пяти байт пишем три с индекса 1: 20/30/40.

  3. Перед копированием возвращаем позицию источника к началу. КопироватьВАсинх копирует от текущей позиции и возвращает фактическое число скопированных байтов.

  4. УстановитьРазмерАсинх(1) удаляет второй байт собственного приёмника. СброситьБуферыАсинх не закрывает поток и не восстанавливает удалённые данные.

  5. Буфер чтения предварительно заполнен девятками. Просим три байта с позицией 2, но в потоке только один: ПрочитатьАсинх возвращает 1, остальные ячейки не превращаются в новые данные.

  6. Закрытие обоих собственных потоков выполняется отдельными попытками с Ждать даже после ошибки. Если закрытие не удалось, ошибка не скрывается.

Как проверить результат

  1. Девять контрольных сравнений дают Истина; буфер после чтения 9/9/20/9/9.

  2. Никаких файлов/сетевых запросов. После успешного завершения оба собственных потока закрыты.

Ожидаемый результат

Показаны смещения, частичное копирование, потеря данных при сокращении и корректный результат чтения на конце потока.

На что обратить внимание

  1. Не считайте, что запрошенное число байтов всегда равно фактически прочитанному.

  2. Не путайте позицию потока, позицию в буфере и его общий размер.

  3. Увеличение размера не гарантирует содержимое новых байтов; здесь только сокращение своих данных.

Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.