Это продолжение статей
Использование классов .Net в 1С для новичков
Использование сборок .NET в 1С 7.x b 8.x. Создание внешних Компонент
Продолжение статьи лежит здесь .Net в 1С. На примере использования HTTPClient,AngleSharp.Удобный парсинг сайтов с помощью библиотеки AngleSharp в том числе с авторизацией аля JQuery с использованием CSS селекторов. Динамическая компиляция
Это статья будет полезна не только 7-кам, но и 8-кам. Да, многое умеет HTTPСоединение и HTTPзапрос. Но многого нет.
Например, нет асинхронных запросов, сжатия трафика, отправки составного содержимого и т.д.
В том числе часто можно найти примеры на C# и иногда быстрее их адаптировать с использованием в 1С HTTPClient.
Про HTTPClient можно почитать здесь
https://msdn.microsoft.com/ru-ru/library/windows/apps/xaml/dn440594.aspx
https://msdn.microsoft.com/ru-ru/library/system.net.http.httpclient(v=vs.118).aspx
Итак, начнем.
Клиент=Врап.СоздатьОбъект(HttpClient);
ДанныеРесурса=Клиент.GetStringAsync("https://msdn.microsoft.com/ru-ru/library/hh551745(v=vs.118).aspx").Result;
Сообщить(Врап.ВСтроку(ДанныеРесурса));
Все очень просто. Но это умеет и HTTPСоединение.
Для начала объявим используемые типы при открытии.
врап=новый COMОбъект("NetObjectToIDispatch45");
HttpClient=Врап.ПолучитьТипИзСборки("System.Net.Http.HttpClient","System.Net.Http.dll");
HttpClientHandler = врап.ПолучитьТип("System.Net.Http.HttpClientHandler");
// Контенты для Post
MultipartFormDataContent=Врап.ПолучитьТип("System.Net.Http.MultipartFormDataContent");
StreamContent =Врап.ПолучитьТип("System.Net.Http.StreamContent");
StringContent =Врап.ПолучитьТип("System.Net.Http.StringContent");
ByteArrayContent=Врап.ПолучитьТип("System.Net.Http.ByteArrayContent");
FormUrlEncodedContent =Врап.ПолучитьТип("System.Net.Http.FormUrlEncodedContent");
DecompressionMethods= Врап.ПолучитьТип("System.Net.DecompressionMethods");
ServicePointManager=врап.ПолучитьТип("System.Net.ServicePointManager");
Dictionary=Врап.ПолучитьТип("System.Collections.Generic.Dictionary`2[System.String,System.String]");
StringBuilder=Врап.ПолучитьТип("System.Text.StringBuilder");
String=Врап.ПолучитьТип("System.String");
HttpUtility=Врап.ПолучитьТипИзСборки("System.Web.HttpUtility","System.Web.dll");
// Сборку AngleSharp.dll поместить в каталог программы
//Для использования Scripting Api
КатаогПрограммы=Врап.ПолучитьТип("System.AppDomain").CurrentDomain.BaseDirectory;
ИмяСборкиAngleSharp=Врап.ПолучитьТип("System.IO.Path").Combine(КатаогПрограммы,"AngleSharp.dll");
AngleSharp_Configuration=Врап.ПолучитьТипИзСборки("AngleSharp.Configuration",ИмяСборкиAngleSharp);
IO_File =Врап.ПолучитьТип("System.IO.File");
Encoding=Врап.ПолучитьТип("System.Text.Encoding");
// В релизе нужно отлавливать ошибки
// врап.ВыводитьСообщениеОбОшибке=ложь;
По мере использования я буду пояснять, для чего тот или иной тип.
Начнем с асинхронного программирования. Часто нужно использовать долгие запросы, или нужно одновременно использовать несколько запросов. К сожалению, 1С этого не позволяет. Поэтому в свой разработке я постарался исправить этот недочет.
Выполнитель=Врап.ПолучитьАсинхронныйВыполнитель();
ДобавитьОбработчик Выполнитель.ПриОкончанииВыполненияЗадачи, ПриОкончанииВыполнения;
//Обработчик события выглядит так
Процедура ПриОкончанииВыполнения(Задача,ДанныеКЗадаче)
// Обязательно нужно отлавливать ошибку в 1С
// Иначе она передается в .Net где обрабатывается там
Попытка
Так как задача может завершиться с ошибкой
Мы должны проверить, и если ошибка нужно предпринять какие то действия
Если (Задача.IsFaulted) Тогда // Ошибка выполнения
Сообщить("Ошибка "+Врап.ВСтроку(Задача.Exception));
Сообщить("Данные к задаче "+Врап.ВСтроку(ДанныеКЗадаче));
иначе
Сообщить("=====Выполнена задача ====");
Сообщить("Данные к задаче "+Врап.ВСтроку(ДанныеКЗадаче));
Сообщить(Врап.ВСтроку(Задача.Result));
КонецЕсли;
Исключение
Сообщить("Ошибка в процедуре");
Сообщить(ОписаниеОшибки());
КонецПопытки
КонецПроцедуры
Вызываем задачу так
Клиент=Врап.СоздатьОбъект(HttpClient);
Задача=Клиент.GetStringAsync("https://msdn.microsoft.com/ru-ru/library/hh551745(v=vs.118).aspx");
Выполнитель.Выполнить(задача,ТекущаяДата());
Для тестов я сделал тестовый Вэб сервис на ASP.Net
Для теста множества асинхронных запросов сделал функцию
[HttpGet]
public async Task<string> GetIdAsync(string id)
{
await Task.Delay(1000);
return id;
}
Имитируем задержку в 1 секунду. Например, нам нужно выполнить 100 запросов.
Процедура TestAsyncНажатие(Элемент)
// Вставить содержимое обработчика.
handler = врап.СоздатьОбъект(HttpClientHandler);
Сообщить(ServicePointManager.DefaultConnectionLimit);
ServicePointManager.DefaultConnectionLimit=100;
Клиент = Врап.СоздатьОбъект(HttpClient,handler);
// Использование заголовков не обязательно
// В данном случае это пример их использования
Клиент.DefaultRequestHeaders.Connection.Add("keep-alive");
CacheControl=Врап.СоздатьОбъект("System.Net.Http.Headers.CacheControlHeaderValue");
CacheControl.MaxAge = Врап.ПолучитьТип("System.TimeSpan").Zero;
Клиент.DefaultRequestHeaders.CacheControl = CacheControl;
Клиент.DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,*/*");
Клиент.DefaultRequestHeaders.Add("Accept-Language", "ru-Ru");
Клиент.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko");
uriSources =ПолучитьСтрокуЗапроса("http://localhost.fiddler:40320/api/values/GetIdAsync/");
Клиент.BaseAddress =Врап.СоздатьОбъект("System.Uri",uriSources);
Выполнитель=Врап.ПолучитьАсинхронныйВыполнитель();
ДобавитьОбработчик Выполнитель.ПриОкончанииВыполненияЗадачи, ПриОкончанииВыполнения;
ВыполненоЗадач=0;
МассивОтветов=новый массив;
stopWatch = Врап.СоздатьОбъект("System.Diagnostics.Stopwatch");
stopWatch.Start();
Для сч=1 По 100 Цикл
Задача=Клиент.GetStringAsync(СокрЛП(сч));
Выполнитель.Выполнить(задача,ТекущаяДата());
КонецЦикла;
КонецПроцедуры
Процедура ВывестиВремя(stopWatch,толькоВремя=ложь)
ts = stopWatch.Elapsed;
String=Врап.ПолучитьТип("System.String");
// Format and display the TimeSpan value.
elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours, ts.Minutes, ts.Seconds,
ts.Milliseconds / 10,0);
Сообщить(elapsedTime);
Если толькоВремя Тогда
возврат
КонецЕсли;
Для каждого стр Из МассивОтветов Цикл
сообщить(стр);
КонецЦикла;
КонецПроцедуры
Процедура ПриОкончанииВыполнения(Задача,ДанныеКЗадаче)
// Обязательно нужно отлавливать ошибку в 1С
// Иначе она передается в .Net где обрабатывается там
ВыполненоЗадач=ВыполненоЗадач+1;
Попытка
Если (Задача.IsFaulted) Тогда // Ошибка выполнения
Сообщить("Ошибка "+Врап.ВСтроку(Задача.Exception));
Сообщить("Данные к задаче "+Врап.ВСтроку(ДанныеКЗадаче));
иначе
//Сообщить("=====Выполнена задача ====");
//Сообщить("Данные к задаче "+Врап.ВСтроку(ДанныеКЗадаче));
//Сообщить(Врап.ВСтроку(Задача.Result));
МассивОтветов.Добавить(Задача.Result);
Если ВыполненоЗадач=100 Тогда
ВывестиВремя(stopWatch)
КонецЕсли;
КонецЕсли;
Исключение
Сообщить("Ошибка в процедуре");
Сообщить(ОписаниеОшибки());
КонецПопытки
КонецПроцедуры
Если бы при синхронном выполнении нам понадобилось бы минимум 100 сек, то при асинхронном уходит порядка 1,5 сек.
Отдельно нужно отметить использование ServicePointManager. Более подробно можно посмотреть здесь
Почему одновременно происходит только два соединения с сайтом
Есть еще вариант дождаться всех запросов
лист=Врап.СоздатьОбъект("System.Collections.Generic.List`1[System.Threading.Tasks.Task]");
Для сч=1 по 10 Цикл
Задача=Клиент.GetStringAsync(СокрЛП(сч));
лист.Add(задача);
КонецЦикла;
Task=Врап.ПолучитьТип("System.Threading.Tasks.Task");
массив=лист.ToArray();
Task.WaitAll(массив);
Для каждого задача из лист Цикл
Сообщить(задача.Result);
КонецЦикла
Но здесь нужно учитывать, что например в выполнитель испольует контекс синхронизации, что может приводить к блокировкам https://habrahabr.ru/post/257221/
Проверил асинхронные методы HttpClient не зависят от контекста синхронизации.
Перед тем как перейти к использованию multipart/form-data, покажу примеры отправки Post запросов.
Процедура ЗакрытьРесурс(Ресурс)
Врап.ПолучитьИнтерфейс(Ресурс,"IDisposable").Dispose();
КонецПроцедуры
Функция ПолучитьСтрокуОтвета(стрОриг)
Стр=СтрЗаменить(стрОриг,"""","");
возврат СтрЗаменить(стр,"
",Символы.ПС);
КонецФункции // ПолучитьСтрокуОтвета()
Функция ПолучитьСтрокуЗапроса(uriSources)
Если не ФлИспользоватьФиддлер Тогда
возврат СтрЗаменить(uriSources,".fiddler","");
КонецЕсли;
Возврат uriSources
КонецФункции
Функция ВыполнитьПост(uriSources,Клиент)
// Контент=Врап.СоздатьОбъект("System.Net.Http.StringContent","Тестовая Строка",Encoding.UTF8,"text/plain");
Контент=Врап.СоздатьОбъект("System.Net.Http.StringContent","Тестовая Строка "+uriSources);
резулт=Клиент.PostAsync(uriSources,Контент).Result;
Сообщить("===================================");
Сообщить(резулт.IsSuccessStatusCode);
Сообщить(Врап.Встроку(резулт.StatusCode));
стр=резулт.Content.ReadAsStringAsync().Result;
Сообщить(ПолучитьСтрокуОтвета(стр));
КонецФункции // ВыполнитьПост()
Процедура TestGetНажатие(Элемент)
// Вставить содержимое обработчика.
HttpClient=Врап.ПолучитьТипИзСборки("System.Net.Http.HttpClient","System.Net.Http.dll");
HttpUtility=Врап.ПолучитьТипИзСборки("System.Web.HttpUtility","System.Web.dll");
Попытка
uriSources =ПолучитьСтрокуЗапроса("http://localhost.fiddler:40320/api/values/");
handler = врап.СоздатьОбъект(HttpClientHandler);
cookieContainer = Врап.СоздатьОбъект("System.Net.CookieContainer");
handler.AutomaticDecompression=Врап.OR(DecompressionMethods.GZip,DecompressionMethods.Deflate);
// Используем cookieContainer для задания куков со стороны клиента. Куки со стороны сервера автоматически сохраняются.
cookieContainer.Add(Врап.СоздатьОбъект("System.Net.Cookie","TestCookie", "TruLyaLya", "/", "localhost"));
handler.CookieContainer=cookieContainer;
handler.UseCookies=истина;
Клиент = Врап.СоздатьОбъект(HttpClient,handler);
DefaultRequestHeaders=Клиент.DefaultRequestHeaders;
DefaultRequestHeaders.Connection.Add("keep-alive");
CacheControl=Врап.СоздатьОбъект("System.Net.Http.Headers.CacheControlHeaderValue");
CacheControl.MaxAge = Врап.ПолучитьТип("System.TimeSpan").Zero;
DefaultRequestHeaders.CacheControl = CacheControl;
DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,*/*");
DefaultRequestHeaders.Add("Accept-Language", "ru-Ru");
DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko");
//Использум BaseAddress, что бы в дальнейшем задавать адрес только ресурса
Клиент.BaseAddress =Врап.СоздатьОбъект("System.Uri",uriSources);
Стр=Клиент.GetStringAsync("GetHeaders").Result;
// В данном случае запрос отправится
//
Сообщить(ПолучитьСтрокуОтвета(стр));
ВыполнитьПост("SendStr",Клиент);
ВыполнитьПост("SendStr2",Клиент);
ЗакрытьРесурс(Клиент);
Исключение
Сообщить(ОписаниеОшибки());
Если Врап.ПоследняяОшибка<>Неопределено Тогда
ПоказатьПредупреждение(,Врап.ПоследняяОшибка.Message);
КонецЕсли;
Врап.ВывестиПоследнююОшибку();
КонецПопытки
КонецПроцедуры
Процедура ПослатьStreamНажатие(Элемент)
// Вставить содержимое обработчика.
uriSources =ПолучитьСтрокуЗапроса("http://localhost.fiddler:40320/api/values/SendStream");
Клиент=Врап.СоздатьОбъект(HttpClient);
// Создаем поток в памяти и записываем в него данные строки в кодировке UTF8
поток=врап.СоздатьОбъект(MemoryStream,Encoding.UTF8.GetBytes("Отсылаемая строка"));
Контент=Врап.СоздатьОбъект(StreamContent,поток);
резулт=Клиент.PostAsync(uriSources,Контент).Result;
Сообщить("===================================");
Сообщить(резулт.IsSuccessStatusCode);
Сообщить(Врап.Встроку(резулт.StatusCode));
стр=резулт.Content.ReadAsStringAsync().Result;
Сообщить(ПолучитьСтрокуОтвета(стр));
ЗакрытьРесурс(Клиент);
КонецПроцедуры
Иногда нужно не только отправить но и получить куки
// Вставить содержимое обработчика.
cookieContainer = Врап.СоздатьОбъект("System.Net.CookieContainer");
handler=Врап.СоздатьОбъект(HttpClientHandler);
handler.AutomaticDecompression=Врап.OR(DecompressionMethods.GZip,DecompressionMethods.Deflate) ;
handler.CookieContainer=cookieContainer;
Клиент = Врап.СоздатьОбъект(HttpClient,handler);
uriSources ="http://www.telerik.com";
Ури=Врап.СоздатьОбъект("System.Uri",uriSources);
Клиент.BaseAddress =Ури;
Стр=Клиент.GetStringAsync("/UpdateCheck.aspx?isBeta=False").Result;
// Пострим все куки присоединенные по этому аресу
Куки = cookieContainer.GetCookies(Ури);
Для каждого кук из Куки Цикл
Сообщить(кук.Name + ": " + кук.Value);
КонецЦикла;
// Можем получить конкретное значение
кук=Куки.get_Item("sid");
Сообщить(кук.Name + ": " + кук.Value);
Отправляемый контекст можно задавать пятью способами
- MultipartFormDataContent,
- StreamContent,
- StringContent,
- ByteArrayContent,
- FormUrlEncodedContent
Выбирайте тот, который удобен. FormUrlEncodedContent это аналог отправики данных Form при Post Submit.
Теперь перейдем к отправке multipart/form-data.
Процедура Multi_PartНажатие(Элемент)
// Вставить содержимое обработчика.
uriSources =ПолучитьСтрокуЗапроса("http://localhost.fiddler:40320");
//uriSources ="http://localhost:40320";
HttpClient=Врап.ПолучитьТипИзСборки("System.Net.Http.HttpClient","System.Net.Http.dll");
MultipartFormDataContent=Врап.ПолучитьТип("System.Net.Http.MultipartFormDataContent");
Клиент = Врап.СоздатьОбъект(HttpClient);
Контент = Врап.СоздатьОбъект(MultipartFormDataContent);
Клиент.BaseAddress =Врап.СоздатьОбъект("System.Uri",uriSources);
// Вариант отправки Ключ-Значение
Значения = Врап.СоздатьОбъект("System.Collections.Generic.Dictionary`2[System.String,System.String]");
Значения.Add("Name", "name");
Значения.Add("id", "id");
// content.Add(new FormUrlEncodedContent(values));
Для каждого КлючЗначение из Значения Цикл
Контент.Add(Врап.СоздатьОбъект("System.Net.Http.StringContent",КлючЗначение.Value),КлючЗначение.Key);
КонецЦикла;
// Вариант отправки двоичных данных из массива
Encoding=Врап.ПолучитьТип("System.Text.Encoding");
СтроковыйКонтент =Врап.СоздатьОбъект("System.Net.Http.ByteArrayContent",Encoding.UTF8.GetBytes("Тестовая строка"));
ContentDisposition=Врап.СоздатьОбъект("System.Net.Http.Headers.ContentDispositionHeaderValue","form-data");
ContentDisposition.FileName ="ПростоСтрока";
ContentDisposition.Name ="attachment";
СтроковыйКонтент.Headers.ContentDisposition = ContentDisposition;
СтроковыйКонтент.Headers.ContentType = Врап.СоздатьОбъект("System.Net.Http.Headers.MediaTypeHeaderValue","text/plain");
Контент.Add(СтроковыйКонтент);
// Вариант отправки двоичных данных из файла
ИмяФайла ="C:/ТестXML";
ПотокФайла =Врап.ПолучитьТип("System.IO.File").OpenRead(ИмяФайла);
ФайловыйКонтент =Врап.СоздатьОбъект("System.Net.Http.StreamContent",ПотокФайла);
ContentDisposition=Врап.СоздатьОбъект("System.Net.Http.Headers.ContentDispositionHeaderValue","form-data");
ContentDisposition.FileName = Врап.ПолучитьТип("System.IO.Path").GetFileName(ИмяФайла);
ФайловыйКонтент.Headers.ContentDisposition = ContentDisposition;
ФайловыйКонтент.Headers.ContentType = Врап.СоздатьОбъект("System.Net.Http.Headers.MediaTypeHeaderValue","application/octet-stream");
Контент.Add(ФайловыйКонтент);
// Вариант отправки двоичных данных из файла но более краткий
ПотокФайла2 =Врап.ПолучитьТип("System.IO.File").OpenRead(ИмяФайла);
ФайловыйКонтент2 =Врап.СоздатьОбъект("System.Net.Http.StreamContent",ПотокФайла2);
Контент.Add(ФайловыйКонтент2,"attachment","TestXml");
requestUri = "api/values/SendFiles";
Результат = Клиент.PostAsync(requestUri, Контент).Result;
стр = Результат.Content.ReadAsStringAsync().Result;
Сообщить(стр);
ЗакрытьРесурс(Клиент);
ЗакрытьРесурс(Контент);
ЗакрытьРесурс(ПотокФайла);
// Вот как выглядит отправляемый запрос
//POST http://localhost:40320/api/values/SendFiles HTTP/1.1
//Content-Type: multipart/form-data; boundary="9f2d525a-7383-46ab-8fc7-419d73486c02"
//Host: localhost:40320
//Content-Length: 811
//Expect: 100-continue
//Connection: Keep-Alive
//--9f2d525a-7383-46ab-8fc7-419d73486c02
//Content-Type: text/plain; charset=utf-8
//Content-Disposition: form-data; name=Name
//name
//--9f2d525a-7383-46ab-8fc7-419d73486c02
//Content-Type: text/plain; charset=utf-8
//Content-Disposition: form-data; name=id
//id
//--9f2d525a-7383-46ab-8fc7-419d73486c02
//Content-Disposition: form-data; filename="=?utf-8?B?0J/RgNC+0YHRgtC+0KHRgtGA0L7QutCw?="; name=attachment
//Content-Type: text/plain
//Тестовая строка
//--9f2d525a-7383-46ab-8fc7-419d73486c02
//Content-Disposition: form-data; filename="=?utf-8?B?0KLQtdGB0YJYTUw=?="
//Content-Type: application/octet-stream
//12345
//--9f2d525a-7383-46ab-8fc7-419d73486c02
//Content-Disposition: form-data; name=attachment; filename=TestXml; filename*=utf-8''TestXml
//12345
//--9f2d525a-7383-46ab-8fc7-419d73486c02--
КонецПроцедуры
Запрос достаточно просто отправить. Вот как это приходится делать на чистом 1С Передача файлов и данных на веб-сервер средствами 1С:Предприятие 8.X методом POST
Стоит отметить использование
handler.AutomaticDecompression=Врап.OR(DecompressionMethods.GZip,DecompressionMethods.Deflate);
который позволяет хорошо сжимать HTML странцы. Например
uriSources ="https://msdn.microsoft.com/en-us/library/system.net.decompressionmethods(v=vs.110).aspx";
handler = врап.СоздатьОбъект(HttpClientHandler);
handler.AutomaticDecompression=Врап.OR(DecompressionMethods.GZip,DecompressionMethods.Deflate) ;
Клиент=Врап.СоздатьОбъект(HttpClient,handler);
Стр=Клиент.GetStringAsync(uriSources).Result;
Сжимает трафик в 5 раз.
Content-Length: 17129 упакованной, против 87 624 неупакованной
К сожалению, объем получился большим. Поэтому продолжение использования HTTPClient и парсинг сайтов выделю в отдельную статью. Так будет проще разбираться.
(0) Я не нашел, какие требования к Framework?
(1) 4.6.1
(0) Перед публикацией могли хотя бы отформатировать код (Alt+Shift+F)
(3) bonv,
Форматировал. Только вот вставка в редактор и редактирование на этом сайте не совсем тривиальная задача
Спасибо за труды, о великий!
Спасибо за оценку трудов моих скромных.
Добавлю удобную объектную надстройку к Retst ApiRefit: The automatic type-safe REST library for .NET Core, Xamarin and .NET
Вкратце можно описать интерфейс
И использовать
У меня не получилось провести тест асинхронных httpзапросов на сервере. Это работать будет только на клиенте?
Это работает только на клиенте, так как идет привязка к событиям, а на сервере нужно ждать когда событие придет
Вся беда в том, что на сервере нельзя сделать
ДобавитьОбработчик Выполнитель.ПриОкончанииВыполненияЗадачи, ПриОкончанииВыполнения
И ОбработкаВнешнегоСобытия.
Поэтому асинхронные только на клиенте.
Извините, возможно плохо искал. А как получить изображение через Стр=Клиент.GetStringAsync(«GetHeaders»).Result; как двоичные данные?
Допустим во втроенном HTTPОтвет Если метод ПолучитьТелоКакДвоичныеДанные
Или есть другой метод получения?
Это в идеале,
Ну или хотябы как записывать
Спасибо, методом проб и ошибок нашел одно из решений которое в вдругой ветке предоставили
Если есть Другие более «правильные» варианты подскажите пожалуйста. Вообще не дотнет разработчик
Ну в Данные ты получаешь массив байтов.
Просто
File=Врап.ПолучитьТип(«System.IO.File»);
File.WriteAllBytes(«B:ПробаУдалитьТестовоеИзображение.jpg»,Данные);
Сергей, спасибо за ответ. Только я имел ввиду Как из запроса получить двоичные данные как объект 1С , вот нашел такое решение. Можно конечно попробовать и по другому
Так же все таки интересуют вопрос ошибок. У меня сложилась ситуация, что когда запрос возвращает ошибку 404 возникает исключительная ситуация в .Net.
Т.е. я не могу обработать task через wait() или waitall(). Не знаю как правильно решить данный момент. Пока сделал что жду в цикле возвращение True хотя бы одного из свойств;
Задача.IsCompleted;
Задача.IsCanceled;
Задача.IsFaulted;
Хотя это немного наверное не правильно…
(1) Ты можешь смотреть IsFaulted в ПриОкончанииВыполнения к которой подключаешься
Нет, я тут не пользуюсь Асинхронным выполнителем, посмотрел что для моей задачи это немного «Неудобно». я просто создаю массив заданий. Причем массив как объект 1С. И когда нужно прохожусь по этому массиву.
Все равно процедура ПриОкончанииВыполнения начнет выполнятся только после завершения формирующей процедуры. Насколько я правильно понимаю
Ну можно по аналогии сhttps://habrahabr.ru/post/307360/
ПриОкончанииВыполнения будет вызываться после завершения Задачи.
Немного проверил работу асинхронного выполнителя. Немного не вижу в нем смысла.
Дело в том, что если мы в Процедуре А() создаем выполнителю множество задач, то результат задач в процедуре-Обработчике мы сможем получить Только!!! После выполнения всей процедуры А. Кроме случаев Когда 1С сама не вызывает «асинхорнные» процедуры , например Вопрос().
Т.е. По сути я могу получить результаты Работы объектов .NET в конце моей процедуры без вызова Асинхронного выполнителя, при этом объекты .NET Выполняют свою работу параллельно работе 1С, что и требует данная тема.
Единственное что дает Выполнитель — это гарантированное выполнение задачи (task), но существенно ухудшает читаемость кода.
Но на выполнение можно сделать проверку в коде 1С циклом как я писал выше
Показать
По поводу WaitAny , не проверил, но думаю дело будет обстоять так же: Если задача из массива задач будет выполнена с ошибкой ( например возврват 404) , то будет вызвано исключение .Net , которое в 1С не отловишь
Тема очень хороша, спасибо.
Ну а ты создавай в Процедуре А только задачи, на это уходит миллисекунды.
А вот время для получения результата уже могут быть секунды.
Нет в данном случае возвращается Task и у него можно проверить IsFaulted
Извиняюсь за вопрос, но на Win 10 x64 получаю стабильно ошибку «Неверное имя объекта» на первой строке Врап = Новый COMОбъект
Нужно ли что-то особенное сделать для Win x64?
Спасибо
Нужно скачать компоненту отсюдаhttps://infostart.ru/public/238584/
https://ru.stackoverflow.com/questions/527763/Как-вызвать-метод-из-c-в-1С/527802#527802
Или если нет денег отсюда