Асинхронное программирование в 1С через использование классов .Net из Native ВК

Публикация № 541698

Разработка - Разработка внешних компонент

.Net Core C# .Native ВК

Это продолжение статьи Кроссплатформенное использование классов .Net в 1С через Native ВК. Или замена COM на Linux II http://infostart.ru/public/541518/ В этой статье покажу, как можно асинхронно вызывать асинхронные методы и вызывать ВнешнееСобытие в 1С из сборки .Net

Это продолжение статьи Кроссплатформенное использование классов .Net в 1С через Native ВК. Или замена COM на Linux II

В .Net сейчас во многих классах есть асинхронные методы. В 1С их можно применять например так

Стр=ъ(Клиент.GetStringAsync(uriSources)).Result;

И напомню про синонимы из предыдущей статьи/ Так добавив синоним

Врап.ДобавитьСиноним(HTTPClient.ПолучитьСсылку(),"ПолучитьСтроку","GetStringAsync");
Врап.ДобавитьСиноним(Task.ПолучитьСсылку(),"Результат","Result");


Я могу использовать все на русском 

Стр=ъ(Клиент.ПолучитьСтроку(адрес)).Результат;

Но можно использовать асинхронные методы так 

        Клиент = ъ(Врап.Новый(HttpClient.ПолучитьСсылку(),handler.ПолучитьСсылку()));
	
	лист=ъНовый("System.Collections.Generic.List`1[System.Threading.Tasks.Task]");
	Для каждого стр из ПолучитьСписокURL() Цикл
		Задача=ъ(Клиент.GetStringAsync(стр));
		лист.Add(задача.ПолучитьСсылку()); 
	КонецЦикла;
	
	Task=ъТип("System.Threading.Tasks.Task");
	
	Пока лист.Count>0 Цикл
		массив=ъ(лист.ToArray());	
		индекс = Task.WaitAny(массив.ПолучитьСсылку());
		Сообщить(индекс);
		результат = ъ(лист.get_Item(индекс)).Result;
		Сообщить(СтрДлина(результат));
		лист.RemoveAt(индекс);
	КонецЦикла;


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

Но нужно делать асинхронный вызов. Для этого создал простенький класс 

public class АсинхронныйВыполнитель
    {// Данные связанные с задачей, что бы понять, что к чему при получении события
        public object ДанныеДляЗадача;
      // Сама задача
        public Task Задача;
     // Имя метода 1С обрабатывающего окончание задачи.
        public String ИмяМетода;
     
        public АсинхронныйВыполнитель(Task Задача, String ИмяМетода, Object ДанныеДляЗадача)
        {
            this.Задача = Задача;
            this.ДанныеДляЗадача = ДанныеДляЗадача;
            this.ИмяМетода = ИмяМетода;
            Задача.ContinueWith((t) =>
            {
                var AW = new AutoWrap(this);
                AutoWrap.ВызватьВнешнееСобытие1С("АсинхронныйВыполнитель", ИмяМетода, AW.ПолучитьСсылку());
            });
        }
    }


А на стороне 1С

Функция ПолучитьДанныеДляЗадачи(адрес,Номер)
	
	объект=ъНовый(ExpandoObject.ПолучитьСсылку());
	объект.Адрес=адрес;
	объект.Номер=Номер;
	возврат объект;
	
КонецФункции // ПолучитьДанныеДляЗадачи()

Процедура ТестАсинхронногоВыполнителяНажатие(Элемент)
		
	Клиент = ъ(Врап.Новый(HttpClient.ПолучитьСсылку(),handler.ПолучитьСсылку()));
	
	лист=ъНовый("System.Collections.Generic.List`1[System.Threading.Tasks.Task]");
	сч=0;
	Для каждого стр из ПолучитьСписокURL() Цикл
          // Получаем задачу
		Задача=ъ(Клиент.GetStringAsync(стр));
        // Получаем данные привязанные к данной задаче
		объект=ПолучитьДанныеДляЗадачи(стр,сч);
	//public static void ВыполнитьЗадачу(System.Threading.Tasks.Task Задача, String ИмяМетода, Object ДанныеДляЗадача)
              
		Врап.ВыполнитьЗадачу(Задача.ПолучитьСсылку(),"ПолученаСтраница",объект.ПолучитьСсылку());
		сч=сч+1;
		
	КонецЦикла;
	
	// Добавим тест на ошибку
	
	Тестовый=ъТип("TestDllForCoreClr.Тестовый","TestDllForCoreClr");
	Тест=ъ(Врап.Новый(Тестовый.ПолучитьСсылку()," Свойство из Конструктора"));
        Thread=ъТип("System.Threading.Thread");
	
	// При передаче 2 вызывается ошибка
	Задача=ъ(Тест.ЗадачаСОшибкойAsync(2));
	объект=ПолучитьДанныеДляЗадачи("ЗадачаСОшибкойAsync",2);
	Врап.ВыполнитьЗадачу(Задача.ПолучитьСсылку(),"ПолученаСтраница",объект.ПолучитьСсылку());

        Задача2=ъ(Тест.ЗадачаСОшибкойAsync(0));
	объект=ПолучитьДанныеДляЗадачи("ЗадачаСОшибкойAsync",0);
	Врап.ВыполнитьЗадачу(Задача2.ПолучитьСсылку(),"ПолученаСтраница",объект.ПолучитьСсылку());

КонецПроцедуры

Процедура   ПолученаСтраница(знач данные)
	
	Задача=ъ(данные.Задача);
	ДанныеДляЗадача=ъ(данные.ДанныеДляЗадача);
	Сообщить("Адрес="+ДанныеДляЗадача.Адрес);
	Сообщить("Номер="+ДанныеДляЗадача.Номер);

       // При возникновении ошибки при выполнении задачи
      // IsFaulted будет истина, а в Exception будет ошибка
	Если (Задача.IsFaulted) Тогда  // Ошибка выполнения
		    ошибка=Задача.Exception;
		    Сообщить("Ошибка "+Врап.ВСтроку(ошибка));
		//  Если сделать как ниже 1С хочет присвоить Задача.Exception новое значение
		//  Даже если оно не было изменено
                // Так как считает, что параметр передан по ссылке
		// Сообщить("Ошибка "+Врап.ВСтроку(Задача.Exception));
	    	   возврат;
	КонецЕсли;
		
	результат=Задача.Result;
	Сообщить(СтрДлина(результат));
КонецПроцедуры	

Процедура ВнешнееСобытие(Источник, Событие, Данные)
	// Вставить содержимое обработчика.
	
	Сообщить("Источник="+Источник);
	Сообщить("Событие="+Событие);
	Сообщить("Данные="+Данные);
	
	Если Источник="АсинхронныйВыполнитель" Тогда
		Данные=ъ(Данные);
		Выполнить(Событие+"(Данные)");
	КонецЕсли; 
КонецПроцедуры


Немного поясню по коду.

Так как в Native ВК нельзя использовать ДобавитьОбработчик то сделаем его эмуляцию передав в АсинхронныйВыполнитель имя метода, который нужно вызвать в 1С 

Врап.ВыполнитьЗадачу(Задача.ПолучитьСсылку(),"ПолученаСтраница",объект.ПолучитьСсылку());


Который будет вызываться при срабатывании внешнего события 

    Если Источник="АсинхронныйВыполнитель" Тогда
		Данные=ъ(Данные);
		Выполнить(Событие+"(ПолученаСтраница)");
	КонецЕсли;


В данном в переменной Событие хранится ПолученаСтраница и будет вызван метод 

ПолученаСтраница(ПолученаСтраница)


Теперь про использование Внешнего события в .Net сборке

Для этого нужно определить поле 

 public Action<string, string, string> ВнешнееСобытие1С;


И установить его из 1С 

    Тестовый=ъТип("TestDllForCoreClr.Тестовый, TestDllForCoreClr, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null");
	Тест=ъ(Врап.Новый(Тестовый.ПолучитьСсылку()," Свойство из Конструктора"));
	
	Делегат=Ъ(Врап.ПолучитьДелегатВнешнегоСобытия1C());
	Тест.ВнешнееСобытие1С=Делегат.ПолучитьСсылку();
	Тест.TestВнешнегоСобытия();


Внутри .Net класса вызвать метод 

this?.ВнешнееСобытие1С("Тестовый", "ТестовоеСообщение", значение);


При этом в 1С вызовется процедура 

Процедура ВнешнееСобытие(Источник, Событие, Данные)
	Сообщить("Источник="+Источник);
	Сообщить("Событие="+Событие);
	Сообщить("Данные="+Данные);
КонецПроцедуры



Я постарался максимально приблизить синтаксис C# в 1С. И по мне, так даже в таком виде проще писать ВК на C#, чем использовать Native API на C++. При этом можно интегрировать использование .Net классов в 1С. Добавляя синонимы можно писать все на кириллице. Можно добавить поддержку итераторов итд.

Сейчас на Windows много всяких ActiveX, кроме того не сложно и самим написать COM компонент на любом языке.
Но это не кроссплатформенно.

Используя .Net Core и данную обертку над объектами .Net в 1С, можно значительно расширить возможности 1С, используя огромное количество библиотек и классов, в них находящихся. И сосредоточиться на разработку языка, наконец добавив замыкания, Linq, указание типа для intellisense (по аналогии с TypeScript). Разбиение модальных диалогов по аналогии с yeld и await в C#. А так же аналоги await для серверных вызовов с замыканиями.

Я понимаю, что данная разработка мало кому интересна. Но мне было интересно её разрабатывать. Кроме того будет интересна кто пробует .Net Core и использут Reflection

Примеры и исходники можно скачать Здесь

Специальные предложения

Комментарии
В избранное Подписаться на ответы Сортировка: Рейтинг всех уровней
1. нормальный такой 90 10.08.16 18:55 Сейчас в теме
вы всегда так пишете? вас в команде один?

я видел вас закидали чем-то невкусным на хабре
2. Serginio 823 10.08.16 20:05 Сейчас в теме
Да. На хабре кто кидает пережде всего реагируют на руслиш. Тема кроссплатформенности, и вызов .Net классов из натива им не интересна.
Оставьте свое сообщение

См. также

Использование классов .Net в 1С для новичков Промо

Практика программирования Разработка внешних компонент Универсальные функции v7.7 v8 Бесплатно (free)

Руководство для новичков. Написав статью http://infostart.ru/public/238584/, я понял, что многие не понимают того, что написано. Поэтому в этой статье постараюсь более подробно остановиться на азах и без кода на вражеском языке (C#)

27.01.2016    76241    Serginio    108    

Работа с журналом регистрации. Выходим за границы платформы

Журнал регистрации Бесплатно (free)

Работа с журналом регистрации нестандартными средствами. А также немного про использование платформы .NET в экосистеме 1С.

12.05.2020    5583    YPermitin    24    

.Net Core, обмен с 1C по TCP/IP между различными устройствами

Разработка внешних компонент v8 Бесплатно (free)

Часто нужно обмениваться данными с клиентом 1С из различных устройств, между клиентами 1С, а также при виртуализации между разными ОС на компьютере. Это кроссплатформенная ВК, позволяющая обмениваться сообщениями по TCP/IP между различными устройствами по определенному протоколу.

28.09.2016    21219    Serginio    8    

Net Core. Динамическая компиляция класса обертки для получения событий .Net объекта в 1С

Разработка внешних компонент v8 Бесплатно (free)

Часто нужно использовать события объектов .Net. Например событие от COM порта, поступление сообщений по WhatsAp, сообщение об изменение в директории итд. Напрямую этого сделать нельзя, но можно сделать класс обертку и через него получать ВнешнееСобытие

14.09.2016    16023    Serginio    1    

.Net Core, 1C, динамическая компиляция, Scripting API

Разработка внешних компонент Практика программирования v8 Бесплатно (free)

Очень часто приходится использовать динамический код в 1С, используя Выполнить или Вычислить. Аналогичная задача и для использования скриптов на .Net. Я постарался показать, как можно скрестить ежа с ужом и получить удобный код. В этой статье много вражеского кода для чистого одноэсника, но все когда-то бывает впервые.

07.09.2016    18959    Serginio    7    

1С, Linux, Excel, Word, OpenXML, ADO, Net Core

Разработка внешних компонент v8 Бесплатно (free)

В данной статье показаны примеры кроссплатформенной работы с файлами Excel и Word (xlsx,docx) с помощью библиотеки OpenXML и Net Core

22.08.2016    21077    Serginio    14    

.Net в 1С. Асинхронные HTTP запросы, отправка Post нескольких файлов multipart/form-data, сжатие трафика с использованием gzip, deflate, удобный парсинг сайтов и т.д.

Разработка внешних компонент Практика программирования WEB v7.7 v8 Бесплатно (free)

Очень часто нужно при работе с HTTP сервисами или сайтами использовать Асинхронные HTTP запросы, отправку на сервер нескольких файлов, использование сжатия трафика. Эта статья про то, как этого легко добиться.

09.03.2016    31653    Serginio    22    

Быстрое создание Внешних Компонент на C#. Примеры использования Глобального Контекста, IAsyncEvent, IExtWndsSupport, WinForms и WPF

Практика программирования Разработка внешних компонент v8 Бесплатно (free)

В большинстве случаев хватает и обычного COM объекта, учитывая, что в 8.х можно использовать события. Но иногда нужно использовать Глобальный Контекст для вызова глобальных функций, таких как Сообщить, NewObject и т.д. Кроме того, для использования форм нужен дескриптор окна 1С. Это продолжение статей Использование сборок .NET в 1С 7.x b 8.x. Создание внешних Компонент. http://infostart.ru/public/238584/ Там же лежат и исходники .NET(C#) для 1С. Динамическая компиляция класса обертки для использования .Net событий в 1С через ДобавитьОбработчик или ОбработкаВнешнегоСобытия http://infostart.ru/public/417830/ 1C Messenger для отправки сообщений, файлов и обмена данными между пользователями 1С, вэб страницы, мобильными приложениями а ля Skype, WhatsApp http://infostart.ru/public/434771/ Использование классов .Net в 1С для новичков http://infostart.ru/public/448668/

15.02.2016    29440    Serginio    13    

Подсветка синтаксиса 1С в текстовых редакторах Atom, Sublime Text, VS Code

Инструментарий разработчика Разработка внешних компонент v8 1cv8.cf Бесплатно (free)

Пакеты, добавляющие поддержку синтаксиса языка 1С:Предприятие 8 в текстовые редакторы Atom, Sublime Text и VS Code. И не только.

02.02.2016    27448    nixel    38    

.NET(C#) для 1С. Динамическая компиляция класса обертки для использования .Net событий в 1С через ДобавитьОбработчик или ОбработкаВнешнегоСобытия

Разработка внешних компонент Математика и алгоритмы v7.7 v8 Бесплатно (free)

Динамическая компиляция класса обертки для использования .Net событий в 1С через ДобавитьОбработчик или ОбработкаВнешнегоСобытия, а так же генерация модулей на C# и 1С для подключения к событиям. Использование DynamicMethod и ILGenerator. Представлены примеры для использовании событий System.IO.FileSystemWatcher (Ожидает уведомления файловой системы об изменениях и инициирует события при изменениях каталога или файла в каталоге.) и SerialPort (обработка сканера штрих кода подключенного к COM порту). Обертка позволяет использовать классы .Net только на языке 1С. Реализация 1C Messenger описанного здесь http://infostart.ru/public/434771/

12.11.2015    46576    Serginio    36    

1С с "плюсами"

Разработка внешних компонент Математика и алгоритмы Универсальные функции v8 Бесплатно (free)

- Разработана методика подключения внешней компоненты, снимающая ограничения на типы данных аргументов и возвращаемого значения. - Проведено документирование основных типов данных (объектов, интерфейсов) платформы. - Разработан объект «Делегат» для реализации функциональных объектов (указатель-на-функцию). - Разработана концепция итератора произвольного доступа для основных контейнеров платформы с целью сопряжения со стандартной C++ библиотекой. - В процессе разработки механизм 1С классов (наследование, интерфейсы) для возможности использования парадигм объектно-ориентированного программирования на уровне кода.

14.10.2015    23072    IntelInside    48    

Генерация штрих-кода для вставки его в 1С при работе в Linux

Разработка внешних компонент v8 1cv8.cf Бесплатно (free)

В Linux есть отличная команда barcode, которая генерирует штрих-коды в векторном формате ps. Но 1С не понимает такие форматы. Более того, barcode генерирует штрих-код на размер листа А4 или Letter. Установка пользовательского размера листа не увенчалась успехом. Но не будем же мы вставлять изображение штрих-кода размером с лист А4… Однако есть способ, как решить данные проблемы.

01.07.2015    16563    rudjuk    4    

Простейший способ создания штрих-кода в формате PNG из командной строки в Linux Ubuntu

Разработка внешних компонент v8 1cv8.cf Бесплатно (free)

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

29.06.2015    12227    rudjuk    15    

Компилирование внешней компоненты AddInNative в ОС Linux

Разработка внешних компонент v8 1cv8.cf Бесплатно (free)

В статье отражены некоторые моменты, которые нужно учесть, чтобы скомпилировать пример 1С-вской внешней компоненты AddInNative в ОС Linux.

14.01.2015    20690    q_i    22    

Использование внешних COM-компонент (.dll) или любых клиентских методов в регламентных заданиях серверной базы.

Практика программирования Разработка внешних компонент Математика и алгоритмы v8 1cv8.cf Бесплатно (free)

Для расширения возможностей платформы 1С существует огромное количество внешних компонент (дополнительные функции, взаимодействие с софтом и железом других производителей, ключи защиты). К сожалению, большинство из них написано на технологии .COM и не могут использоваться на сервере. Для использования в регламентных заданиях серверной базы их приходится переписывать на Native API. Однако, иногда нет возможности переписать компоненту на новую технологию, но нужно вызвать ее в регламентном задании на сервере.

10.12.2014    45761    ekaruk    51    

Обработка изображений 1С средствами .Net framework

Разработка внешних компонент v8 1cv8.cf Бесплатно (free)

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

19.04.2013    20712    Elisy    13    

Подсистема "COMExchange": ускорение выгрузки запросов ADO или «игра с огнём».

Практика программирования Разработка внешних компонент v8 1cv8.cf Россия Бесплатно (free)

Описана поддержка подсистемой "COMExchange"работы с ВК GameWhithFire.dll и в частности ускоренная выгрузка результата запроса ADO средствами ВК.

11.03.2013    19961    yuraos    4    

Простой пример создания ActiveX-control на Qt

Практика программирования Разработка внешних компонент v8 1cv8.cf Бесплатно (free)

Мне была поставлена задача разработать некий ActiveX-control. Так как основным языком программирования для разработки у нас используется C++, то C# не рассматривался. Я решил выбрать Qt, так как он мне интересен. Создание ActiveX объектов на Qt достаточно простой процесс, в примерах к QtCreator есть несколько вариантов, показывающих как можно использовать ActiveQt (например этот). При написании компонента пришлось много времени потратить на поиск ответов на казалось бы простые вопросы, по крупицам их собирать. В результате я получил, что требовалось и решил написать простой пример, чтобы ускорить процесс старта разработки ActiveX-control другим. Сразу обращу внимание, что не описываю всю технологию ActiveQt, подробную информацию можно получить в документации Qt Assistant и в интернете (например здесь), это пример и пара интересных на мой взгляд моментов.

25.02.2013    9190    theshadowco    3    

Finger-биометрия в 1С

Разработка внешних компонент v8 Россия Бесплатно (free)

О различных методиках использования сканеров отпечатков пальцев в 1С.

02.07.2012    27292    fixin    22    

Решение проблем с регистрацией внешних компонент в терминале

Разработка внешних компонент Розничная торговля Учет ТМЦ Розничная торговля Учет ТМЦ v8 УТ10 Россия УУ Бесплатно (free)

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

22.09.2011    68207    Spacer    41    

Новая версия 1С:Предприятие 8.2 конфликтует с C# и .Net framework

Практика программирования Разработка внешних компонент v8 1cv8.cf Бесплатно (free)

Суть конфликта 1С 8.2 с C# и .Net framework в следующем. В версии 8.2 1С анонсировала новый способ написания внешних компонент 1С с использованием так называемого Native API. Самое интересное, что на C# предложенный подход реализовать невозможно, а реализация Native API на VC++/CLI теоретически возможна, но при попытке подключения DLL, скомпилированных с опцией /CLR, происходит зависание 1С (версия 8.2.13.202). Еще один конфликт – в новой версии 1С нет поддержки технологии ActiveX, на основе которой многие разработчики вставляли в формы 1С свои WinForms-приложения.

15.12.2010    21350    Elisy    128    

Учим внешнюю компоненту правильному склонению не только ФИО, но и должностей, и подразделений (ЗУП 2.5)

Разработка внешних компонент Практика программирования v8 ЗУП2.5 Россия Бесплатно (free)

Многие из нас сталкивались с проблемой неверного склонения должностей и подразделений внешней компонентой склонения ФИО. Результат при этом может напоминать следующее: 1.Именительный "Главный специалист" 2.Родительный "Главныя специалиста" 3.Дательный "Главныю специалисту " 4.Винительный "Главныя специалиста " 5.Творительный "Главныем специалистом " 6.Предложный "Главные специалисте " Метод борьбы с данным недугом предлагаю ниже.

21.11.2010    61245    director04    64