Closed Toveal closed 10 months ago
Из синтаксис помощника:
Объект внешней компоненты (Add-in object) <ИмяМетода>Асинх (
Async) Доступен, начиная с версии 8.3.18.
Платформа 1С сама добавляет эти функции к объекту компоненты, со стороны Rust ничего не требуется для реализаии асинх методов. Мб, имеется в виду для COM?
Нет, именно для Native. Проблема в том что основной поток блокируется после вызова асинх функции компоненты. Либо я что-то делаю не так, либо асинх не имеет смысла. Ставить Tokio не имеет смысла т.к. 1с сама распоряжается как запускать компоненту (как я понимаю). Пример: хочу сделать GET запрос куда-либо и вызываю из 1С асинх. http://localhost:3001/ping просто mock сервер с задержкой в 5 сек
use native_api_1c::{native_api_1c_core::ffi::connection::Connection, native_api_1c_macro::AddIn};
use std::sync::Arc;
#[derive(AddIn)]
pub struct Addin {
#[add_in_con] // соединение с 1С для вызова внешних событий
connection: Arc<Option<&'static Connection>>, // Arc для возможности многопоточности
#[add_in_func(name = "TestPing", name_ru = "ТестПинг")]
#[returns(Str)]
pub test_ping: fn(&Self) -> String,
}
impl Addin {
pub fn new() -> Self {
Self {
connection: Arc::new(None),
test_ping: Self::test_ping,
}
}
pub fn test_ping(&self) -> String {
return match reqwest::blocking::get("http://localhost:3001/ping") {
Ok(_) => "OK".to_string(),
Err(_) => "Err".to_string(),
};
}
}
&НаКлиенте
Асинх Процедура ГоАсинх()
Имя = "Test";
МакДВД = гетМак();
Адрес = ПоместитьВоВременноеХранилище(МакДВД);
Рез = Ждать УстановитьВнешнююКомпонентуАсинх(Адрес);
Подключена = Ждать ПодключитьВнешнююКомпонентуАсинх(Адрес, Имя, ТипВнешнейКомпоненты.Native);
СтруктураВозврата = Новый Структура("Ошибка, ОписаниеОшибки", Истина);
Если Не Подключена Тогда
СтруктураВозврата.ОписаниеОшибки = "Не подключился";
Сообщить("Не подключили");
КонецЕсли;
КомпонентаОбъект = Новый ("Addin." + Имя + ".Addin");
Результат = Ждать КомпонентаОбъект.ТестПингАсинх();
Сообщить("Прошли по асинху");
КонецПроцедуры
Функция гетМак()
Возврат РеквизитФормыВЗначение("Объект").ПолучитьМакет("Макет");
КонецФункции
Постфикс "асинх" не делает функцию параллельной к основному потоку, и как я понимаю, нужен, чтобы при вызове метода компоненты ее непосредственный вызов выполнился в порядке очереди, которая накопилась у рантайма 1С. Я не проверял, но мне кажется, например, если вызвать метод компоненты в обработке нажатии кнопки на форме, то вызов через асинх даст возможность кнопке визуально отжаться, надо будет глянуть :)
Если вам нужна параллельность, то асинх не для этого, для этого есть внешние события компоненты, которые можно вызывать из параллельных потоков в Rust.
Добавлю, что это несколько странно, что приходится играть в эти гадалки, т.к. подробной документации от 1С нет(а может и есть, но ее фиг найдешь). Наверное, по этой же причине Native компоненты до сих пор не могут возвращать или принимать что-то сложнее чисел и строк
В принципе как и всегда, нашел информацию про 1С не на ИТС. В статье на инфостарте пишут:
...И в целом эти все потоки выполняются почти параллельно. Но есть в системе старый способ обеспечивать параллельность в работе, который пришел к нам из Windows 3.0, с помощью эмуляции параллелизма через очередь сообщений в Главные окна. Принцип работы заключается в том, что система выполняет какое-то задание через очередь сообщений и затем после возвращает управление системе, ожидая следующего задания. Так это работает и сейчас для взаимодействия с пользователем через GUI в окнах. Асинхронный режим, который реализуется в 1С, тоже использует очередь сообщений. Когда мы запускаем задание через асинхронную функцию, платформа 1С создает для неё обработчик и либо сразу запускает его, либо после того, как обработает текущее сообщение окна. Мы же получаем эмуляцию многопоточного режима...
Думал хоть где-то использовать Асинх. Придется юзать потоки. Спасибо
Вопрос. Никак не могу найти нормальную информацию о том как сделать так, чтобы компонента могла работать в асинхе. Нашел информацию на ИТС:
Больше всего вопросов вызвал вот этот текст: Саму внешнюю компоненту не требуется отдельно перерабатывать для поддержки работы в асинхронном режиме, однако необходимо выполнить перекомпиляцию существующей внешней компоненты для поддержки асинхронной работы.
Подскажите если кто шарит