Pull to refresh

Comments 255

Смысл показывать здесь код, который никому не пригодится?
Вы, конечно, молодец, но это здесь совершенно не нужно, причем даже вредно — новички могут ужаснуться.
На самом деле здесь много интересного. Это и Proxy и Promise для TypeScript.
Работа с CEF, а так же и Net Core. Кроме того здесь показано как просто можно использовать классы .Net очень близко к кодированию на C#. Здесь очень много информации на любой вкус.
Я, как человек, который первый раз видит этот код могу четко сказать, что он никого ничему не научит.
Учатся на простых и ясных примерах, а не на коде, который интересен только его разработчику.
Ну у меня и не было цели учить новичков. Главная моя цель показать как можно легко использовать классы .Net в TypeScript и каким образом это достигается. Для меня такие статьи очень познавательны. Здесь собрано много вещей, аналогов которых нет, или их просто сложно найти. На многие вопросы ни на одном форуме не было ни одного ответа. Ну и опять же чем сложен этот пример?
Сразу прошу прощения за руслиш.

// Получим Тип из сборки лежащей в каталоге приложения
let Тестовый = Net.GetType("TestDllForCoreClr.Тестовый", "TestDllForCoreClr");
// Создадим объект используя new
let TO = new Тестовый("Свойство из Конструктора");
// Получим ExpandoObject
var EO = TO.ПолучитьExpandoObject();
let Имя=EO._Имя;// Свойства через _
let Число=EO._Число;
let делегат = EO._ВСтроку;
let res= делегат());// Вызовем как делегат
 // Для ExpandoObject можно вызвать как метод
 res= EO.ВСтроку());// Для ExpandoObject



Показано как просто можно использовать классы .Net Core
Главная моя цель показать как можно легко использовать классы .Net в TypeScript и каким образом это достигается

Но зачем, зачем это делать? Если у меня есть доступ к .net, то я уже и без TS обойдусь.

На самом деле я не видел где есть полный доступ к классам .Net из браузера. Если подскажешь то буду благодарен. Сейчас например для Linux нет аналога WPF, а моя разработка помогает использовать кроссплатформенный .Net Core в браузере, или просто расширить возможности браузера за счет классов .Net
На самом деле я не видел где есть полный доступ к классам .Net из браузера. Если подскажешь то буду благодарен.

Не подскажу, потому что этого нет. А нет этого, потому что это небезопасно.


Сейчас например для Linux нет аналога WPF, а моя разработка помогает использовать кроссплатформенный .Net Core в браузере

Угу. В каком? У меня шесть, что ли, устройств на трех операционных системах, 5 браузеров — на скольких из них это будет работать?

Ну в статье же написано про CEF

Внизу статьи показаны ссылки на программы которые можно запустить. В начале статьи
Можно сделать определенную конфигурацию CEF для всех платформ и можно делать кросспалатформенные декстопные приложения.


Ребята читайте пожалуйста внимательнее, или подскажите как лучше написать.
Ну в статье же написано про CEF

Написано, ага. CEF работает на Windows Phone? iOS?


Внизу статьи показаны ссылки на программы которые можно запустить.

Агу. С сайтом (который у меня не собирается). Спасибо, но нет.

Для WinFone и прочего есть xamarin. А вот для Linux ничего нет.
Сайт это TypeScript? то там нужно npm install сделать, что бы установить создать папку node_modules

Для WinFone и прочего есть xamarin.

Да там много что есть, только получается, что решение как-то не очень кросс-платформенное.


Сайт это TypeScript? то там нужно npm install сделать, что бы установить создать папку node_modules

… и npm у меня тоже нет. Про что и речь.

Ну речь то про Angular. Я просто еще тот вэб программист. Просто JS созданные на TS напрямую не идут. Речь про await. Но внутри есть Test.html его можно посмотреть и там есть различные тесты. Правда без Proxy

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

Я сейчас разберусь как можно локально использовать TypeScript и ужимок не будет. Если хочешь помоги. Буду благодарен. Все ts файлы лежат в папке ap.
Еще раз я один и мне приходится изучать кучу вещей. И времени просто не хватает.
Кстати а можешь пояснить, за что минус? Проблема в том, что для Linux сейчас не UI. При этом много крика про импортозамещение.

Не ко мне вопрос, не мой минус.


А крики про импортозамещение как были криками, так и останутся. О каком импортозамещении вы говорите, используя .net core и CEF?

Еще раз. У тебя есть приложение на WPF, UWP. C выходом NetStandard 2 возможности .Net Core приблизятся к UWP/
Можно достаточно легко перевести приложение под WPF на Angular 2 и использовать под Linux
Можно достаточно легко перевести приложение под WPF на Angular 2

Серьезно?


(Не говоря уже о том, что приложение для iOS вряд ли будет на WPF)


Понимаете ли, в моих конкретных реалиях оказалось выгоднее под каждую мобилку писать свое собственное приложение с нативным интерфейсом, потому что бэкэнд все равно, как и полагается бэкэнду, на сервере. И все эти прыжки и ужимки с "кросплатформенным-html-js-в-кросплатформенном-браузере-который-общается-с-кроссплатформенным-.net" умерли еще на первой стадии, когда не взлетел кроссплатформенный интерфейс.


При этом в соседнем окне у меня Slack, написанный как раз на чем-то типа Electron (просто не помню деталей), и он как раз хорошо справляется — но у него, опять-таки, вся логика на сервере, он просто не отличается от того, что можно запускать в браузере.

Ну так CEF то есть и по WPF http://opensource.spotify.com/cefbuilds/index.html

Опять же я просто показываю решение. Я в самом начале написал, что это мало кому интересно. Просто делюсь опытом. Я же тебя не заставляю использовать.
Ну так CEF то есть и по WPF http://opensource.spotify.com/cefbuilds/index.html

Что такое "CEF по WFP"?


Опять же я просто показываю решение. Я в самом начале написал, что это мало кому интересно. Просто делюсь опытом. Я же тебя не заставляю использовать.

Вы делитесь опытом, мы делимся мнениями по поводу вашего опыта. Все логично.

Прошу прощения. Wpf здесь лишнее.
Спасибо. Просто я сейчас не смогу отвечать. Много работы. Но все равно огромное спасибо!
Я думаю можно таким образом смешать Electron+Angular2, например, как UI, и .NET как бекенда.

Если вы хотите .net на бэкенде — поставьте его там и выставьте сервис.

Городить сервис на http\ws и клиентскую часть? Появятся накладные расходы на сериализацию данных, отправку запроса, десериализацию, обработку…
А тут можно все в одном процессе. У такого подхода есть плюсы и минусы, но он заслуживает право существовать.

… у конверсии данных JS-.net нет накладных расходов? JS выполнется в том же домене, что и .net? Не поверю.


(не говоря уже о том, что бэкенд в подавляющей части случаев все равно удаленный)

В статье есть тесты на вызовы
Скорость вызова без Proxy 60к вызовов в секунду
Скорость вызова с прокси Proxy 45k вызовов в секунду
Скорость вызова итератора 160k вызовов в секунду

Можно же скачать исходники и все пощупать.

… и как это говорит об отсутствии накладных расходов?

Они минимальны по сравнению с http\ws.
При этом часто нужно работать с торговым оборудованием или дисками и прочим оборудованием. Сейчас кстати пишу оберки для использования событий .Net классов
Они минимальны по сравнению с http\ws.

Цифры в студию.

Еще раз
Скорость вызова без Proxy 60к вызовов в секунду
Скорость вызова с прокси Proxy 45k вызовов в секунду
Скорость вызова итератора 160k вызовов в секунду

Вызываем функцию

 public int ПолучитьЧисло(int число)
        {

            return число;
        }

Код такой
// Протестируем скорость вызовов без Proxy
            var start = new Date();
            let count = 100000;
            let result = 0;
            for (let i = 0; i < count; i++)
                result += window.CallNetMethod(Id, "ПолучитьЧисло", [1]);

            this.speed = Math.round(count / (new Date().getTime() - start.getTime()) * 1000);
      

        // Протестирум это же но через Proxy

            start = new Date();
            result = 0;
            for (let i = 0; i < count; i++)
                result +=TO.ПолучитьЧисло(1);

            this.speedWithProxy = Math.round(count / (new Date().getTime() - start.getTime()) * 1000);

           // Протестируем скорость вызова итератора
            let iter = TO.GetNumbers(count);
            start = new Date();
            result = 0;
            for (let i of iter)
                result += i;

            this.spedCallIterator = Math.round(count / (new Date().getTime() - start.getTime()) * 1000);

            NetObject.DeleteNetObjets(TO, Тестовый, iter);
    }

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

Она показывает, что скорость вполне приемлема для большинства задач.
Кроме того в большинстве случаев тебе не нужны циклы, в большинстве случаев тебе нужен некий функционал Net классов. Например можно перенести готовую логику WPF на Angular 2 или Electron.
C http\ws у тебя будет значительно больше работы, чем использовать классы напрямую. Тем более работа с оборудованием ни как не спасет.

Ну для интереса можно вызвать Http сервис и подсчитать. Это несложно. Но, что то мне подсказывает, что межпроцеесоное взаимодействие максимум на 1к вызов в секунду выйдет.
Она показывает, что скорость вполне приемлема для большинства задач.

А у out-of-process-сервера — неприемлема?

Я предлагаю еще вариант использования. Есть альтернатива out-of-process-сервера. Чем это плохо,
Для кого то может быть и неприемлема. При этом нужно отдельно держать http\ws сервер.
Я предлагаю еще вариант использования. Есть альтернатива out-of-process-сервера. Чем это плохо,

Да ничем это не плохо, если это стабильно работает и не требует лишних усилий. Но с моей личной точки зрения, писать в двух экосистемах, если можно обойтись одной — это уже лишние усилия.


При этом нужно отдельно держать http\ws сервер.

Вы правда не знаете других способов межпроцессного взаимодействия, кроме http/ws (и я даже не буду спрашивать, что такое "ws" в этой паре)?

Угу http/ws это надстройка на Tcp/IP.
Но проблема сериализации, десериализации остается. При этом что HTTP что Вэб сервисы это сериализация через текст. Можно конечно использовать WCF на netNamedPipeBinding, что я часто и делаю? но поверь трудозатраты несоизмеримы с прямым использованием
Угу http/ws это надстройка на Tcp/IP.

Ну и зачем мне TCIP/IP на одной машине?


Но проблема сериализации, десериализации остается.

А у вас данные между двумя виртуальными машинами совсем без сериализации/десериализации гуляют, да?


Можно конечно использовать WCF на netNamedPipeBinding, что я часто и делаю? но поверь трудозатраты несоизмеримы с прямым использованием

"Прямое использование" — это .net-.net. Да, не вопрос, несоразмеримы. Но то, что сверху — это уже куча трудозатрат, и еще понадобится вложить.

Ну там просто копирование в одном процессе.
Я показал пример, где различия минимальны. Очень близко к .net-.net
Ну там просто копирование в одном процессе.

Копирование чего, простите?


Я показал пример, где различия минимальны. Очень близко к .net-.net

А можно метрику .net-.net в тех же условиях?

Пожалуйста, на первом том примере она будет минимальна, ибо основное время это получение данных с сайта.

"Она будет минимальна" — это ни о чем. Цифры, цифры и еще раз цифры.

У тебя для этого все есть. У меня нет времени.

Тут уже как-то говорили, что не стоит делать утверждения, которые потом "нет времени" доказывать.

Я тебе сказал, что там основное время это получение данных с сайта. Если ты не веришь, то сам и проверь.

… если там основное время — это получение данных с сайта, то накладные расходы на межпроцессное взаимодействие никого уже не волнуют. Что, собственно, и требовалось доказать.

Кто то выбирает один процесс, а кто то как ты несколько.
Что и так было ясно.

Вот только у каждого выбора есть своя аргументация. Кто-то аргументирует выбор одного процесса тем, что много накладных расходов… вот только подтвердить это пока не удалось.

Я аргументиру это тем, что писать на один процес легче.
При этом обработку данных можно вынести в .Net сборку,
а там где скорость не критична можно использовать стандартные библиотеки.
Есть большой выбор в отличие от твоего подхода. За каждой мелочью премся на сервер.
Я аргументиру это тем, что писать на один процес легче.

Легче писать в одной экосистеме. А когда вы пишете чудовище франкенштейна, где в каждый момент времени не понятно, в каком контексте выполняется код, и происходит, когда я записываю в свойство — это не легче.


(мы всего этого успели наестся еще во времена remoting).


Вот я вызвал из клиент-сайда (JS) метод сервер-сайда (.net). Тот создал ConcurrentDictionary, запустил отдельный поток для расчетов, и вернул словарь мне. Отдельный поток продолжает писать в словарь. Внимание, вопрос: когда я буду вызывать методы на словаре на стороне JS, они будут видеть "новое" состояние?


Есть большой выбор в отличие от твоего подхода. За каждой мелочью премся на сервер.

Это не "мой подход", а тот подход, который вы мне приписываете. Я этого нигде не говорил.

Угу чем это отличие от HTTP запроса? Я знаю что за классы я использую.
Ну и чем ремотинг от HTTP запроса отличается?
Через await и увидит. Сейчас прикручиваю события.

Ну а как ты же говоришь о превосходстве out процессов. А значит есть сервер.
Угу чем это отличие от HTTP запроса? Я знаю что за классы я использую.
Ну и чем ремотинг от HTTP запроса отличается?

Это мы пропустим, как не имеющее отношения к делу.


Через await и увидит. Сейчас прикручиваю события.

В ConcurrentDictionary нет ни async, ни событий. Я спрашиваю про простое dict["abc"].


Ну а как ты же говоришь о превосходстве out процессов. А значит есть сервер.

Не сервер, а другой процесс. И да, поскольку есть другой процесс, и это эксплицитно, интерфейс меняется с chatty на chunky, поэтому никакого "за каждой мелочью".

В ConcurrentDictionary нет ни async, ни событий. Я спрашиваю про простое dict["abc"].

Кажется, вы не поняли всего прикола его решения. Нет никакого dict["abc"] на стороне JS! Там делается вызов get_Item("abc"), который прокси-объектом пробрасывается в .NET-код, где и выполняется.

Я, к сожалению, понял. И приводит это к еще более chatty-интерфейсу, чем можно было бы сделать, потому что — если я ничего не пропустил — там вообще нельзя вернуть объект с той стороны. Или структуру все-таки можно?

Да вы что! У структуры же могут тоже быть методы! И их может понадобится вызвать!

Значит, я правильно предположил, и только базовые типы (с потерей, я так понимаю, возможности вызывать методы на них). Кстати, а что со строками?


Зато это объясняет, почему нет сериализации (ну, почти нет). Зато любые утверждения о том, что с этим просто работать после этого однозначно в топку.

Я же написал в чем отличие
Прежде всего видим главные отличия от C#. Для получения свойства нужно добавить "_"

let Default = Configuration._Default;

Для вызова асинхронного метода нужно добавить ключевое слово async:

let document = await Context.async.OpenAsync(address);

Для вызова дженерик метода, если нельзя вывести типы по параметрам то аргументы указываем в массиве:

let rows = ApiExtensions.QuerySelectorAll([IHtmlTableRowElement], document, rowSelector);

Ну и главное, нужно вручную удалить ссылку на объект со стороны .Net

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

Это все синтаксические отличия. Не интересно. А меня интересует рантайм.

Структуры боксятся и можно вызывать методы наравне со статческими методами, методы дженериков с автовыводом типа. Поддержка параметров по умлчанию, params
Структуры боксятся

Все? Вообще все?


let price = netCalculator.getPrice();
if (price >= 100)
  ...

netCalculator — это объект от .net, с бизнес-логикой внутри. Какого типа price?

Мы говорим про мою проект. Там доступ к свойствам и методам производится через рефлексию. А в рефлексии все боксится

… а теперь посмотрите на второй вопрос.

По твое логике int. Они кстати просто копируются.

А для ссылочных типов на стороне JS нужно вызывать Equals или op_ или compare
Но на стороне JS нужно вызывать Equals или op_ или compare

То есть price — все-таки не number?

Ну в Net понятия number. Будет либо int либо Double. Другие типы не поддерживаются JS и нужно их оборачивать через ChangeType

Я, вообще-то, про JS говорю. То, что GetPrice возвращает Decimal — это данность. А вот какого типа джаваскриптовая переменная price, в которую вы записали это значение?

Будет объект на стороне Net. Либо можно конвертировать в строку как я это делаю для 1С.
Сейчас посмотрел в текущей реализации делается так
if (Тип == typeof(System.Decimal)) return ((Decimal)obj).ToString(CultureInfo.InvariantCulture);
Будет объект на стороне Net.

С которым нельзя работать, как с числом. Круто, да, очень просто для разработчика на стороне JS.


Сейчас посмотрел в текущей реализации делается так
if (Тип == typeof(System.Decimal)) return ((Decimal)obj).ToString(CultureInfo.InvariantCulture);

… и любая проверка типа на стороне JS радостно говорит "да это ж не число". Да?

Ну что делать если на стороне JS нет понятия decimal/
Он может либо из строки сделать свой Decimal на примере https://github.com/MikeMcl/decimal.js

Можно для Decimal делать конвертацию в этот объект.
Опять же я выдал продукт и собираю мнения, как его улучшить, и нужно ли это вообще
Ну что делать если на стороне JS нет понятия decimal

Работать в тех терминах, которые в JS есть. А если их нет — по крайней мере, не прикидываться, что это "просто".


Опять же я выдал продукт и собираю мнения, как его улучшить, и нужно ли это вообще

Вот вам и говорят, что не нужно.

А кто прикидывается? В чем проблема распарсить строку в объект?

Про ненужно мне давно известно, только странно, что ты это так доказываешь.
Я не успеваю работать.
А кто прикидывается? В чем проблема распарсить строку в объект?

В том, что это лишнее действие, нарушающее, собственно, постулат "работать просто".

А что делать если JS этого не поддерживает?
Что ты кстати будешь делать через out process?
А что делать если JS этого не поддерживает?

Если не поддерживает, значит, в JS с этим работать неудобно.


Что ты кстати будешь делать через out process?

Получать данные в тех типах, которые JS поддерживает.

Иииии? Но вот данные храняться в Decimal. Что делать?
Ну и я передаю в виде строки.
Иииии? Но вот данные храняться в Decimal. Что делать?

Преобразовывать в семантически понятный JS тип, очевидно. У меня decimal-данные прекрасно летают между двумя машинами в JSON, и ничего.

Угу JSON это та же строка. Но вот только Decimal и Double разные вещи.
Угу JSON это та же строка.

Внезапно, нет.


Но вот только Decimal и Double разные вещи.

В .net, да. Но в JS[ON] нет ни того, ни другого, есть number.

Дааа? а как данные передаются?

Угу и как JS сконвертирует число которое не подходит под Double?
Дааа? а как данные передаются?

В виде строкового представления. Не путайте представление с сообщением.


Угу и как JS сконвертирует число которое не подходит под Double?

А откуда вы вообще взяли понятие Double? Мне всегда казалось, что в JS есть только number, и будут использоваться его ограничения.

Все я прекращаю диалог. Совершенно нет времени, а диалог совсем не конструктивный. Списибо за общение.
В CEF есть только Double и Int
В CEF есть только Double и Int

… так это проблемы выбранного вами CEF.

http://stackoverflow.com/questions/3454965/javascript-decimal-values

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

Если Number поддерживает Decimal, то могу передавать на строну CEF бинарные данные, из CEF преобразовывать в объект со строковым представлением числа и флагом, что это Decimal. На стороне JS парсить по аналогии с Json. Нет проблем.

Да понятно, что "нет проблем", только каждое такое дополнение — это увеличение кода, который надо написать и поддерживать (что понижает "простоту" решения) и потери в производительности (что снижает привлекательность решения с этой точки зрения).

Все делается в прокси. И я тебе давал ссылку на https://mikemcl.github.io/decimal.js/
Опять же, все вычисления делаются на стороне Net в моем случае, где этих ограничений нет и я могу использовать Decimal как объект
Все делается в прокси.

Который тоже надо писать и поддерживать.


Опять же, все вычисления делаются на стороне Net в моем случае

Так я про это с самого начала и говорил: проще все сделать на .net и не возиться.

Вогт я написал прокси один раз. Зачем мне его поддерживать
Так сделай на линуксе с UI. И покажи нам всем. Я буду тебе только благодарен.
Вогт я написал прокси один раз. Зачем мне его поддерживать

Потому что нет программы без ошибок, во-первых, и вы никогда не учтете всего с первого раза во-вторых.


Так сделай на линуксе с UI. И покажи нам всем.

Берете asp.net core приложение и открываете в браузере. Enjoy.

Ну с этой точки зрения тот же CEF постоянно переписывается. Но есть вещи которые не трогаются годами.

Иииии. При этом за всеми данными ползать на сервер. Наша песня гарна нова?

То есть ты не различаешь понятия Декстоп, где мы отвязаны от сервера?

Я понимаю, что моя разработка ни кому не нужна, но я лично никакой радости не имею переводя wpf приложение на asp.net core. Это вы батенька мазохист. В моем случае мне нужно только переписать код формы, а всю остальную логику перекомпилировать под .Net Core. Учитывая, что NetStandard 2 не загорами, то переделки минимальны.
Ну с этой точки зрения тот же CEF постоянно переписывается. Но есть вещи которые не трогаются годами.

Для этого сначала надо потратить годы на то, чтобы их написать. Это не так-то просто.


То есть ты не различаешь понятия Декстоп, где мы отвязаны от сервера?

Да все я различаю, а еще я оцениваю количество нужных усилий.


В моем случае мне нужно только переписать код формы, а всю остальную логику перекомпилировать под .Net Core.

Дадада, конечно, переписать код формы с WPF на JS — это совершенно тривиальное занятие. А маппинг из JS на .net core — так и вовсе волшебным образом появился.


"Только", да.

Там кода прокси максимум строк 100. Это далеко не годы.
Ты даже не знаком с моей разработкой. Но действуешь по принципу «Не читал, но осуждаю»

Я тебе показал, что код на TS мало отличается от кода на C#. Мало того можно нагенерить ds.ts и наслаждаться Intellisense

Но опять же хозяин барин. Я же в начале статьи написал, что моя разработка мало кому интересна. Ты яркое подтверждение моих слов.
Там кода прокси максимум строк 100.

Это пока не начали всплывать вещи типа "а как сконвертировать decimal", "а что делать с событиями", "а как передать делегат", "а как передать объект".


Я тебе показал, что код на TS мало отличается от кода на C#.

Мы уже выяснили, что нет: как минимум, нет автоматического управления памятью (которое есть и в TS, и в C#), нельзя передавать объекты, и так далее.


А уж в WPF-то вообще не C#-ный код, там биндинги и прочее декларативное счастье. Кстати, для того, чтобы оно работало, нужны события...

Как передать делегат и объект написано. Ты не читаешь.
События мало отличаются от асинхронных вызовов.

Ну ручное управление мало отличаются от using ты и в C# должен своевременно закрыть ресурсы.

События я как раз пишу. Но ты мне не даешь закончить. Ты хоть работаешь?
Как передать делегат и объект написано. Ты не читаешь.

Ну да, написано: передача объектов не поддерживается. Думаю, что и с делегатами то же самое.


Ну ручное управление мало отличаются от using ты и в C# должен своевременно закрыть ресурсы.

Ээээ, серьезно? А то, что ресурсов, требующих using, намного меньше, чем обычных объектов, вы не в курсе? Я не пишу using для строк, я не пишу using для массивов и вообще коллекций — да чего там, я реже пишу using, чем не пишу.


События я как раз пишу. Но ты мне не даешь закончить. Ты хоть работаешь?

Конечно, нет. У меня вечер, зачем мне работать?

Написано, что не поддерживается передача JS объектов. Но название статьи
«TypeScript использование классов .Net Core „
Так, что ты пиши правильно. В JS нет понятия делегатов. Там все свойства и методы тоже.

А, днем чего делал. Заметь мы скоро рекорд побъем по количеству сообщений.
Дай мне написать события.
Написано, что не поддерживается передача JS объектов. Но название статьи
«TypeScript использование классов .Net Core „

Понимаете ли, в чем дело… под использованием люди разные вещи понимают. И когда я не могу собрать на лету анонимный объект, чтобы запихнуть его в, скажем, логгер, или в транспорт, или куда-то еще — это ограничение использования. И когда я не могу получить структуру — это тоже ограничение использования. И так далее, далее, далее. Ваш прокси на 100 строк потому и укладывается в 100 строк, что не дает привычных возможностей — только те, которых лично вам, как вы думаете, достаточно.


В JS нет понятия делегатов.

Правда? А коллбек-функция — это что?


Дай мне написать события.

Да я вас вроде за руку и не держу...

Это функция. Делегат это чисто C# понятие. Вернее правильнее даже мультиделегат.
Если ты посмотришь на Proxy, то заметишь, что есть get, set и apple. А вот вызова как метода объекта нет.
То есть объект может быть функцией и иметь свойства. Свойства могут быть функциями.

Еще раз. Я завожусь и не могу остановиться пока не отвечу.
А вопросы ну никакие, но ничего не могу с собой поделать. Это по сути шизофрения. Но где то она помогает, а где то как с тобой мешает.
Делегат это чисто C# понятие.

На самом деле, нет — как минимум оно используется во всем .net. Но не суть, заменим делегат на колбек. Колбеки передавать можно? А лямбда-выражения?

Молодец. Прошу прощения неправильно высказался.

Это называется JS функция. После разговора с тобой у меня есть желание на все наплевать и прекратить мои мучения. Наверное не будет.
Зачем? Кому это нужно? Одни минуса. Немного карму подняли и плюсов дали. Огромное спасибо за это коллегам.

Конечно я не брошу и по инерции сделаю и поддерку объектов и методов, для начала только на время вызова функции.

Это называется JS функция.

Лямбда-выражения? Которые Expression<Func...>? Нет, совсем нет.

А при чем тут деревья выражений?
Ладно пошел я спать. И тебе советую. Прошу извинить если не буду больше отвечать. Море дел. Спокойной ночи?
А при чем тут деревья выражений?

При том, что я про них и говорил, когда спрашивал про лямбда-выражения. Когда у тебя ощутимая часть бизнес-кода на них построена — как-то поневоле задумываешься, можно ли их использовать в предлагаемом новом инструменте.

Да уж не далеко я ушел. Деревья выражений и лямбда выражения это не деревья выражений

Лямбда-выражения

Лямбда-выражение — это анонимная функция, с помощью которой можно создавать типы делегатов или деревьев выражений. С помощью лямбда-выражений можно писать локальные функции, которые можно передавать в качестве аргументов или возвращать в качестве значений из вызовов функций. Лямбда-выражения особенно полезны при написании выражений запросов LINQ.


Класс Expression

Дерево выражений является представлением данных в памяти, лямбда-выражения. Дерево выражений делает структуру лямбда-выражения прозрачной и явной. Можно взаимодействовать с данными в дерево выражения, так же, как и с любой другой структурой данных.

Возможность использовать выражения как структуры данных включает для интерфейсов API получение кода пользователя в формате, который можно проверить, преобразования и обрабатываются особым образом. Например LINQ to SQL реализацию доступа к данным использует это средство для переводы деревьев выражения в инструкции Transact-SQL, которые можно оценить в базе данных.

Многие стандартные операторы, определенные в Queryable класса имеют один или несколько параметров типа Expression.


Давай спокойной ночи.

Лямбда-выражения — это синтаксический сахар, который позволяет получить на выходе как функцию, так и дерево выражений. Меня интересовала вторая ипостась (потому что про первую мы уже выяснили, что ее нет). Когда я пишу типичный код productRepository.Matching(p => p.Cost < 15), я хочу так дальше и писать, а не думать, как мне извратиться в JS/TS.


Впрочем, у меня вообще много монадического кода типа


message
.If(c => m?.Credentials?.Certificate?.IsValid)
.With(m => m.Registration)
.CheckNull(() => new InvalidOperationException())
.Map<Client>()
.Select(c => c.Secrets)
.Do(Add)

А теперь, значит, выставим message как прокси-объект в TS ииии понеслась.

Да понятно, что можно то, можно это, можно что-нибудь еще. Но каждое такое "можно" добавляет сложности в ваш прокси (о чем я, собственно, и говорил выше).


Более того, вот возьмем мой пример, первый вызов (я убрал null-coalescing, чтобы не мешал), и перенесем на сторону JS/TS:


message.If(m => m.Credentials.Certificate.IsValid)

message — это объект .net (через прокси), If — extension method на этом объекте. Предположим, что вы уже умеете обрабатывать extension methods (а умеете ли?), и развернем это в статический вызов:


Maybe.If(message, m => m.Credentials.Certificate.IsValid)

Окей. Вызов статического метода (.net), первый параметр — объект (.net), второй — анонимная функция (JS). Вызываем метод, первый параметр разворачиваем из-под прокси, для второго создаем прокси (нам же нужно передать что-то на сторону .net) к JS-функции. If внутри себя что-то делает (проверку на null, на самом деле) и вызывает переданную ему функцию — то есть, опять наш прокси — передав ему все тот же объект. Тот, в свою очередь, вызывает функцию из-под прокси, передав ей в качестве параметра прокси от .net-объекта (хорошо, если тот же самый, что раньше, а то ведь может и новый создать).


Ура, мы дошли до внутренностей анонимной функции (для этого дважды пересекли границу CEF, ага). Первое, что мы видим — обращение к свойству .net-объекта, а это значит, что мы снова вызываем прокси, разворачиваем это свойство, вызываем свойство на .net-объекте, получаем ответ, заворачиваем в (новый) прокси, возвращаем обратно… чтобы повторить еще дважды. Результат этого — bool — мы возвращаем из функции, оно попадает в прокси функции, потом в If, и тот уже возвращает исходный объект (или null), который в свою очередь возвращается в JS в виде прокси.


Одна строчка кода. От пяти до семи прокси создано (в зависимости от того, умеете ли вы понимать, что для возвращенного объекта уже был прокси) и что-то порядка семи пересечений границы CEF (считал на глаз). Одна строчка кода.


И эти люди говорят нам за перформанс.

Давай я пока поддержку Эвентов допишу. Немного осталось. А потом уже за JS объекты возьмусь. Ты сможешь протестировать и дать рекомендации.

Там под Net надо свой Linq делать с автоосвобождением ссылок.
Сейчас не готов это обсуждать. Не начем. Буду делать учту твои доводы.
Там под Net надо свой Linq делать с автоосвобождением ссылок.

Вот-вот. Сто строк, ага.

Нет это не Proxy.
Ты хочешь столько, сколько я один сделать не могу. Но я могу использовать ScriptingApi? могу динамически создавать сборки. Вариантов куча.
Еще раз никто же тебе не запрещает писать на C# и использовать нормальный Linq.
Еще раз никто же тебе не запрещает писать на C# и использовать нормальный Linq.

Бинго, я про это с самого начала и говорю: намного проще писать на C# и использовать нормальную функциональность.

А кто твой код то будет вызывать из браузера?
Он сам внедрится?

Вы не поверите: браузер. Люди прекрасно писали интерактивные приложения до появления JS, в чистом сервер-сайде.


Впрочем, это сейчас неудобно, спорить не буду. Но я могу взять готовый клиент-сайд, их сейчас тысячи, натравить его на "стандартный" REST — и получить типовое приложение, механизмы работы которого понятны и предсказуемы.

Я разве запрещаю. Делай как хочешь. А кому то может и мой подход понравится. На вкус и цвет товарищей нет
Ну а вообще так как мы можем получить итератор то можем использовать для этих целей TS
LinQ for TypeScript

import { List } from 'linqts';

let arr = new List<number>([1,2,3,4,5])
    .Where(x => x > 3)
    .Select(y => y * 2)
    .ToArray(); // > [8, 10]

let query = people.Join(pets,
    person => person,
    pet => pet.Owner,
    (person, pet) =>
        ({ OwnerName: person.Name, Pet: pet.Name }));


И есть еще куча аналогов на TS.

Скорость выборки итератора порядк 170к в секунду.
Здесь лучше использовать гибридный подход
Ну а вообще так как мы можем получить итератор то можем использовать для этих целей TS (LinQ for TypeScript)

Не-а.


Во-первых, не везде, где нужны деревья, есть итераторы (первый же пример — маппинг).


Во-вторых, предлагать использовать клиентскую итерацию поверх данных из БД — это, конечно, живо. Тривиальный джойн с фильтрацией — и вместо одной строчки (причем неполной) мы вытащим из БД пару (сотен) тысяч, в полную ширину.


Спасибо, нет.

Я вообще то не предлагаю все делать на стороне JS. Ты также можешь написать свои Dll которая может подгружаться по web.
Нет смысла все писать на JS/ Вся прелесть в использовании сборок .Net из JS
Я вообще то не предлагаю все делать на стороне JS.

Ну то есть фраза "получить итератор и использовать TS" мне показалась, ага.

Можно использовать и итератор. Все зависит от ситуации. У тебя есть выбор где это делать В сборке или в JS.

У меня есть только иллюзия выбора, потому что в любом разумном сценарии такие операции надо переносить в сборку. Что, собственно, и приводит к ситуации "все сделать в .net", о которой я говорил раньше.

И использовать из JS. Код то сам не вызовется.

… это если мне зачем-то вообще сдался JS.

Молодец!!! Повеселил. Ты хоть название то статьи вспомни.
Вот когда кажется
https://learn.javascript.ru/number
Все числа в JavaScript, как целые так и дробные, имеют тип Number и хранятся в 64-битном формате IEEE-754, также известном как «double precision».

https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Number

Number.isSafeInteger()  Определяет, является ли переданное значение безопасным целым числом (числом в диапазоне от -(2:53 — 1) до 2^53 — 1).

https://msdn.microsoft.com/ru-ru/library/364x0z75.aspx

Ключевое слово decimal обозначает 128-разрядный тип данных. По сравнению с типами данных с плавающей запятой, диапазон значений типа decimal меньше, а точность выше, благодаря чему этот тип подходит для финансовых расчетов. В следующей таблице представлен приблизительный диапазон значений и точность для типа decimal

… правильно же казалось: есть тип number, ограничения которого вы и озвучили.

По сути это Double. Посмотри на максимальное целое значение. Несмотря на то, что число 64 разрядное. Но реально в CEF два вида int и Double.
Int64 приводится к Double. CEF это по сути Google Chrome
Но реально в CEF два вида int и Double.

… личные детали реализации CEF.


Впрочем, это тоже не важно. Ну да, мы нашли непредставимое в JS значение. Это усложняет задачу, не упрощает ее.

Кстати говоря о out process мы то говорим о поддержке браузером протоколов.
А в нем только HTTP. Могу завтра проверить скрорсть передачи и получении числа.
Кстати говоря о out process мы то говорим о поддержке браузером протоколов.

Это вы говорите только о браузере. Но если мы говорим о браузере, то ваше решение неприменимо вовсе, потому что оно, как мы помним, не браузерное.


А в нем только HTTP.

Это, кстати, неправда.

Как это не браузерное? Что такое по твоему CEF?

Ну говоря о неправде нужно давать ссылки. Мне ведь тоже интересно, что нон поддерживает.
Как это не браузерное? Что такое по твоему CEF?

"The Chromium Embedded Framework (CEF) is a simple framework for embedding Chromium-based browsers in other applications."


Ну говоря о неправде нужно давать ссылки. Мне ведь тоже интересно, что нон поддерживает.

Как минимум вебсокеты поддерживаются современными браузерами. Обычно.

То есть тебе такое слово как browsers ни о чем не говорит?

Так скажем, что Web сокеты не далеко ушли от HTTP. Так на чем меряем скорость?
Возьму ASP.NET Core, Angular 2, SignalR для чайников

Там и тот и другой вариант можно использовать
То есть тебе такое слово как browsers ни о чем не говорит?

Я еще немножко умею читать контекст, и отличаю embedded browser от обычного браузера. В embedded browser я не ограничен HTTP, мне доступен любой транспорт, на который мне хватило таланта его написать.


Так скажем, что Web сокеты не далеко ушли от HTTP.

Безосновательное утверждение, прямо скажем. На множестве маленьких сообщений (а именно это происходит в UI обычно) вебсокеты могут выигрывать до десяти раз.

Ны дык он и создан для Декстопа. Используй любые протоколы. И давай сравним их по скорости и удобству использования. На Proxy кстати теряется процентов 30. Но они удобны.

Завтра напишу на await цикл
Релиз TypeScript 2.1

и посмотрим.

Как ты считаешь, кто победит ws или мой JS-CEF-NET
На Proxy кстати теряется процентов 30. Но они удобны.

Мы уже обсуждали "удобство" вашего решения, и вы меня не убедили.


Как ты считаешь, кто победит ws или мой JS-CEF-NET

В каком соревновании?

Если честно не собираюсь я тебя ни в чем убеждать. Просто я завожусь, а потом не могу уснуть итд. Понятно, что ты меня тролишь. Но это могя разработка, мое детище, моя кровинка. И конечно я её защищаю.

А насчет соревнования так это количество вызовов в секунду.
Так как мы не используем прокси, твой ws должен выдать не меньше 60к вызовов в секунду.
А насчет соревнования так это количество вызовов в секунду.

Бессмысленная метрика, которая не показывает оверхед в реальных бизнес-задачах.


По ссылке, которую я приводил немного раньше, демонстрируют 10к/сек, т.е. 0.1мс на запрос. Для всех применений, кроме игровых, этого достаточно.

Ну и сравни с моими 60к. При этом еще и мой старый процессор 3.3.
То есть не нужно писать тестов. Решили, что мое решение быстрее. Ок. и на этом хорошо.

А если сравнивать с итератором то там вообще 170к

Реальные бизнес задачи лежат в сборках Net. Задача TS это UI, а там кода немного, но вызвать код удобнее из сборки при это типизированно, чем ползать на сервер пусть и на ws. Нужно писать обработчики получения сообщений. Нет автоматически переноса интерфейса с сервера. На нескольких методах ничего, а вот на сотнях уже завал. Но…
Ну и сравни с моими 60к.

Разница меньше порядка (и это, заметим, неоптимизированное решение).


То есть не нужно писать тестов. Решили, что мое решение быстрее.

Я ничего не решал. А вы, конечно, вольны решать что угодно.


Задача TS это UI, а там кода немного, но вызвать код удобнее из сборки при это типизированно, чем ползать на сервер пусть и на ws.

Вы про типизированные webapi тоже не слышали, да? У вас нет никакой типизации для работы с .net "из коробки", она вся на .d.ts построена — так никто не мешает те же .d.ts сгенерить для сервера. Так что нет никакой разницы.


Нужно писать обработчики получения сообщений. Нет автоматически переноса интерфейса с сервера.

… и как люди вообще веб-интерфейсы пишут, а?

В чем оно не оптимально?
Спасибо!
Угу. Сколько методов в обычном классе Net. И сколько тебе нужно написать на сервере для поддержания норального декстопного приложения с сотнями форм?

Вот и я про это? Например для Rest есть возможность использовать Refit
Но это не как в wcf, где контракты можно импортировать.
В чем оно не оптимально?

В том, что не озвучена задача, которую решали, и критерии оптимизации.


Сколько методов в обычном классе Net. И сколько тебе нужно написать на сервере для поддержания норального декстопного приложения с сотнями форм?

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


Но это не как в wcf, где контракты можно импортировать.

Вообще-то и в Rest можно, просто нет такой же общепринятой методики описания контракта, как wsdl. Но есть swagger, raml, api blueprint, что там еще было?.. Но не суть, в вашем-то случае у вас все общение пропьетарно, вы можете в качестве контракта использовать сам .net-класс, по которому и генерить .d.ts.

Как это нельзя. В первом же примере мы работаем исключительно с объектами.
https://github.com/AngleSharp/AngleSharp

При этом этом в асинхронном методе оговаривается
 //Метод расширения
            //Task<IDocument> OpenAsync(this IBrowsingContext context, string address);
            let document = await Context.async.OpenAsync(address);
            // Не могу установить результат асинхронной функции класс Proxy с Target fuction
            // Поэтому для объектов нужно вручную обернуть
            document = NetObject.WrapResult(document, true);

… и что происходит, когда мы дальше делаем document.Abc = "def"? Вызов метода на стороне .net runtime, или присвоение данных в какое-то локальное хранилище, или что-то третье?

Ту не смотрел код Test.html там есть тест
var  SB = window.CallNetMethod(0,"Новый",["System.Text.StringBuilder"]);

		var  res = window.CallNetMethod(SB.Id,"Append",["Первая строка"]);
                window.DeleteNetObject(res.Id);

		var ToStr= window.CallNetMethod(SB.Id,"ToString");
	alert(ToStr);


                 window.CallNetPropertySet(SB.Id,"Capacity",40);
                
                 res=window.CallNetPropertyGet(SB.Id,"Capacity");
                 alert(res);


Вызывается Handler CEF.

 bool CallNetObjectFunction::Execute(const CefString& name,
		CefRefPtr<CefV8Value> object,
		const CefV8ValueList& arguments,
		CefRefPtr<CefV8Value>& retval,
		CefString& exception)  {


		const size_t argumentsCount = arguments.size();
		vector<wstring> savedstrings;
		NetObjectToNative::tVariant* Params = nullptr;

		int Target = arguments[0]->GetIntValue();
		wstring MethodMame = arguments[1]->GetStringValue().ToWString();

		CefRefPtr<CefV8Value> params;

		size_t  argCount = 0;
		if (argumentsCount == 3)
		{


			params = arguments[2];

			if (!params->IsArray())
			{
				exception = CefString(L"Для вызова метода 3 параметр должен быть массивом");
				return true;

			}
			argCount = params->GetArrayLength();


		}

		if (argCount > 0)
		{
			savedstrings.reserve(argCount);
			Params = new NetObjectToNative::tVariant[argumentsCount];
			NetObjectToNative::tVariant* Param = Params;

			for (size_t i = 0; i < argCount; ++i)
			{

				NetObjectToNative::ConvertCEFtoNet(params->GetValue(i), &Param[i], savedstrings);
			}

		}
		wchar_t*  Error = nullptr;
		NetObjectToNative::tVariant RetVal;

		bool res = mD->pCallAsFunc(Target, MethodMame.c_str(), &RetVal, Params, argCount, &Error);

		if (res)
		{

			retval = NetObjectToNative::ConvertNetToCef(&RetVal, true);
		}
		else
		{
			if (Error)
				exception = CefString(std::wstring(Error));
			delete Error;
		}

		if (Params) delete[] Params;

		return true;
	}
bool res = mD->pCallAsFunc(Target, MethodMame.c_str(), &RetVal, Params, argCount, &Error);


вызывается статическая функция на стороне .Net
 public static bool CallAsFunc(int Target, IntPtr ИмяМетодаPtr, IntPtr ReturnValue, IntPtr МассивПараметров, int РазмерМассива, IntPtr ErrorPtr)
        {
            object result = null;
            var res = CallAsFuncAll(Target,ИмяМетодаPtr,МассивПараметров,РазмерМассива,ErrorPtr, out result);

            if (!res)
                return res;

            bool IsReturnValue = ReturnValue != IntPtr.Zero;

            if (IsReturnValue)
                РаботаСВариантами.УстановитьОбъектВIntPtr(ОбернутьОбъект(result), ReturnValue);
            else if (result is AutoWrap)
            {
                AutoWrap temp = result as AutoWrap;
                СписокОбъектов.RemoveKey(temp.ИндекасВСписке);
            }
            return true;

        }

В этом примере нет ни одного объекта на стороне JS, только прокси. Каждое обращение к любому их свойству/методу (т.е., любое имеющее бизнес-смысл) передается в .net runtime.

Не в .Net а в CEF, из CEF через статические функции в Net

… то есть в итоге все равно в .net.


(ну и да, на один уровень проксирования больше делает хуже, а не лучше)

Ну напрямую из JS в Net не получится. Но скорости достаточно. По сравнению с 1С в два раза выше.
Но скорости достаточно

Ну то есть некоторые люди сражаются с тем, чтобы не было лишнего боксинга, а вам "достаточно скорости", когда каждое обращение проходит через две границы (+боксинг, +рефлексия). Кул.


На этом фоне, честное слово, любые претензии к скорости работы с Out-of-process лишены всякого смысла.

То ты говорил, что out process это круто. Еще раз скорость вызова все равно на порядки выше чем Out-of-process.
То ты говорил, что out process это круто.

Это, кстати, неправда. Я говорил, что вынос .net-кода в отдельный процесс с нормальным межпроцессным взаимодействием — нормальное решение.


Еще раз скорость вызова все равно на порядки выше чем Out-of-process.

Цифры в студию.

Ну так ты и дай твои цифры. Я в 1С работаю с out серверами там тормоза менее 1кб/ сек. Предоставь свои цифры.
Кстати со стороны натива-Net скорость около 500к/сек.

Ну так ты и дай твои цифры. Я в 1С работаю с out серверами там тормоза менее 1кб/ сек. Предоставь свои цифры.

Э нет. Вы делаете утверждения о скорости вызова, вам их и доказывать.

Я тебе говорю, что 1кб/ сек, а ты опровергай. Как же научный метод?

Научный метод говорит нам, что отрицание не доказывается. Про чайник Рассела не слышали, нет?

Ты можешь провести тест и опровергнуть мои утверждения.
Ты кстати мои тесты проверял?
Ты можешь провести тест и опровергнуть мои утверждения.

Могу, но не хочу. Бремя доказательства лежит на утверждающем.

Я тебе утверждаю на своих наблюдениях. Давай какой out process ты хочешь.

Я "хочу" цифры, на основании которых вы утверждаете, что накладные расходы на межпроцессное взаимодействие на порядки выше, чем накладные расходы при вашем решении.

На основании COM Excel, 1C83.Application. 1C77.Application
Я в свое время мерял скорость она была ниже 1k/

Извините, но эти унылые старики меня не интересуют. Начиная с того, что меня не интересует COM и заканчивая тем, что меня не интересуют неповоротливые монстры.


Возьмите специально написанный сервер на .net, возьмите pipes, возьмите хороший сериализатор, типа Protobuf или Bond, и сравните.

Ну так ты предлагаешь и сделай тесты и сравним.
При этом напиши удобную сериализацию десериализацию из браузера.

Не, не интересно.

Мы то говорим о браузерах. А для поддержки пайпов нужно писать плагин.

Для воспроизведения моего примера нужно вызвать синхронно

var request = new XMLHttpRequest();
request.open('GET', '/bar/foo.txt', false);  // `false` makes the request synchronous
request.send(null);

if (request.status === 200) {
  result+=Number(request.responseText);
}


Или предлагай свой вариант.
Мы то говорим о браузерах.

Как я уже сказал, это вы зачем-то ограничиваетесь браузерам.


Для воспроизведения моего примера нужно вызвать синхронно

long polling? web sockets? Не, не слышали...

Это SignalR. Слышал и использую ASP.NET Core, Angular 2, SignalR для чайников
Только все это протоколы поверх HTTP либо очень близки
https://ru.wikipedia.org/wiki/WebSocket

Несмотря на «похожесть» новых запросов и ответов на запросы и ответы протокола HTTP, они таковыми не являются. Например, в запросе есть тело, но в заголовках поле «Content-Length» отсутствует (что нарушает соглашения HTTP).

Серверной части следует поддерживать оба вида клиентов и отличать их по наличию или отсутствию в запросе заголовков Sec-WebSocket-Key1 и Sec-WebSocket-Key2.
Это SignalR.

Это не SignalR. Это способы связи с серверами. SignalR их просто поддерживает.


Только все это протоколы поверх HTTP либо очень близки

Близки-то близки, да вот только оверхед у них другой совершенно. Открытие-закрытие соединения не бесплатно.

SignalR это протокол выбирающий оптимальный протокол обмена.
Работая с SignalR ты не заботишься о том, какой протокол поддерживает клиент.

А keep-alive на что. Так мне самому стало интересно. Меряем на ws и HTTP.
SignalR это протокол выбирающий оптимальный протокол обмена.

SignalR — это не протокол, это библиотека, с конкретными решениями и соглашениями. Не для всяких задач она будет эффективна.


А keep-alive на что.

А он в вашем примере был? Вот то-то и оно.

А как по твоему называются действии по выбору оптимального протокола?

Вообщето практически все браузеры добавляют keep-alive в заголовки.

Ну дык кто победит ws или моя разработка? Ты сразу оговори код. А то у тебя постоянные метания.

А как по твоему называются действии по выбору оптимального протокола?

Так и называются: действия по выбору оптимального протокола.


Ну дык кто победит ws или моя разработка?

По критерию?


Ты сразу оговори код.

А зачем? Речь же идет о концептуальном решении, а не о конкретном коде. Конкретный код может проигрывать, другой конкретный код — выигрывать. И оба они быть совершенно неприменимыми для решения бизнес-задачи.


Так что начинать надо с решаемой задачи (и граничных условий)

Спасибог! Посмеялся.

Ну и как с тобой разговаривать. То с начала завел меня на, то что межпроцессное взаимодействие это круть, теперь коцептуальное решение.

Вот объясни почему ты WPF решение пишешь без out process, обязано быть out process. Казалось бы в чем разница?
То с начала завел меня на, то что межпроцессное взаимодействие это круть

Вы, кажется, с кем-то другим разговариваете. Я всего лишь говорю, что межпроцессное взаимодействие — это не та проблема, чтобы мешать разработке (для типовых сценариев, конечно).


Вот объясни почему ты WPF решение пишешь без out process, обязано быть out process.

(а) я не знаю, что вы называете out process
(б) я не понимаю, что именно вы пытаетесь спросить
(ц) я вообще не пишу WPF-решения, меня от WPF тошнит

(a) Это взаимодействие между двумя приложениями.
(б) Зачем писать 2 приложения, если можно все сделать в одном?
На чем пишешь UI?
Зачем писать 2 приложения, если можно все сделать в одном?

Миллион ответов, первый из которых: удобство разработки благодаря разделению ответственностей.


(собственно, архитектура тонкого клиента так и выросла в свое время)


На чем пишешь UI?

На asp.net mvc, когда очень припрет, либо у нас тут есть под рукой самописный веб-фреймворк.

То есть ты декстопное приложение всегда пишешь с использованием asp.net mvc?

Дааа. Не понять мне Вас. И не мне одному Angular 2 и .Net Core
То есть ты декстопное приложение всегда пишешь с использованием asp.net mvc?

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

А моя разработка как раз об этом. Поэтому мы и не поймем друг друга.
Мало того еще есть и пример

// Получим Тип из сборки лежащей в каталоге приложения
let Тестовый = Net.GetType("TestDllForCoreClr.Тестовый", "TestDllForCoreClr");
// Создадим объект используя new
let TO = new Тестовый("Свойство из Конструктора");

Так и будет
let value=dict.get_Item("abc");


К сожалению в JS [] уже забиты для доступа свойств.

Ты это как хочешь называй. Но это по сути и есть внепроцеесный сервер, раз ты к нему обращаешься.
Так и будет

… и, как уже сказано ниже, это будет вызовом метода внутри .net runtime. Ведь так?


Как мне положить в этот словарь объект? Ну не знаю там,


dict.set_Item("abc", {a: 1, b: "cd", f: {g: "h"}}

?


Ты это как хочешь называй. Но это по сути и есть внепроцеесный сервер, раз ты к нему обращаешься.

… и что?

Да set_Item
Можешь почитать Использование классов .Net в 1С для новичков

Ну так конечно не получится. Пока не поддерживаются JS объекты.
Но они будут поддерживаться правда только на время вызова.

Кроме того можно использовать динамическую компиляцию
.Net Core, 1C, динамическая компиляция, Scripting API
Ну так конечно не получится. Пока не поддерживаются JS объекты.

Во-от.


Но они будут поддерживаться правда только на время вызова.

… то есть переданный на сторону .net-рантайма объект будет скопирован целиком, правильно? И вещи типа "передали, на этой стороне поменяли свойство, на стороне рантайма видно новое" работать не будут?

Нет будет держаться ссылка на стороне CEF
а из CEF можно вызвать метод JS функции метода
AsyncMetodCall->ExecuteFunctionWithContext(CallbackContext, globalObj, args)

Так я повторюсь.


var v = {a: "abc"}
netObj.SetValue(v);
netObj.Print(); //abc
v.a = "def";
netObj.Print(); //что будет напечатано?
Еще раз. Я говрил, что на данный момент нет поддержи JS объектов, но она будет только на время вызова.

А на время вызова такой код сработает. Я работаю над этим.
В том числе как фильтр в Where итд

Я еще раз спрошу: что будет напечатано?

«def». Работаем со ссылкой, а не копируем в строку

Вот тогда-то у вас утечки памяти и начнутся.

Для JS объектов есть подсчет ссылок на стороне CEF.
И будут реализованы только на время вызова.
А для Net объектов нужно вручную удалять. Это прописано.
И будут реализованы только на время вызова.

Вы все говорите "время вызова"… время вызова чего? Сколько конкретно живет ссылка на v в моем примере?


А для Net объектов нужно вручную удалять. Это прописано.

В принципе, одного этого достаточно, чтобы перестать с этим работать.

На время вызова метода
var v = {a: «abc»}
netObj.SetValue(v);// Только на время этого вызова

Но мы можем из метода SetValue вызывать методы v
netObj.Print(); //abc // Здесь уже нет никакго v
netObj.Print(); //abc // Здесь уже нет никакго v

Приехали. Если нет никакого v, то напечатать abc не получится, потому что abc — оно внутри v.

Если будет внутри методпа
voit TestJS(dynamic v)
{
netObj.SetValue(v);
netObj.Print(); //abc
v.a = "def";
netObj.Print(); 

}


А можно организовать систему так же как и .Net и можно держать ссылки на них.
У меня просто времени нет для реализации. Кроме того я прекрасно понимаю, что это писанина в стол.
Если будет внутри методпа

Внутри JS-метода или .net-метода?


А можно организовать систему так же как и .Net и можно держать ссылки на них. У меня просто времени нет для реализации.

Неудивительно: если бы я взялся написать свой аналог системы управления памятью в .net, у меня бы тоже времени не было...

в JS нет понятия
void TestJS(dynamic v)



Там организация достаточно простая спис

class ХранилищеОбъектов
    {
        const int НачальноеКоличествоЭлементов = 64;
        ЭлементХранилища[] Элементы = new ЭлементХранилища[НачальноеКоличествоЭлементов];
        internal int КоличествоЭлементов = 0;
        int РазмерМассива = НачальноеКоличествоЭлементов;
        internal int FirstDeleted = -1;
        static SpinLock sl = new SpinLock();


Но нужно вручную из него удалять. К сожалению в JS нет финализатора или подсчета ссылок. В Electron есть
в JS нет понятия

Тогда это опять пример не о том, потому что я показываю вызов из JS, и Print я вызываю тоже из JS.

Еще раз я тебе уже расписывал.
На стороне CEF я могу сохранить ссылку

Создадим класс

Class JSObjectProxy
{

//
CefRefPtr<CefV8Value> JSObject;
vector<JSObjectProxy*> listProxy;
CefRefPtr<CefV8Context> context; // Или один класс содержащий контекст

// Этот метод дергаем из .Net Core
 bool CallJsMethod(wchar_t* method,tvarstruct* params, int argCount,wchar_t** Error)
{

  здесь вызываем 
JSObject_->ExecuteFunctionWithContext(callback_context_, NULL, args, retval, exception, false)) 



и если функция возвращает в retval JSObject то создаем JSObjectProxy
и добавляем его в listProxy, что бы ссылка не обнулилась.
}

}

vector<JSObjectProxy*> это вектор который создается в Методе Exexute
члены которого будут уничтожаться при выходе из метода.
На стороне CEF я могу сохранить ссылку

… с каким сроком жизни? Вернемся к примеру:


var v = {a: "abc"}
netObj.SetValue(v);
netObj.Print(); //abc
v.a = "def";
netObj.Print(); //def?

Напомню, это код на JS, и это условия задачи. В какой момент CEF сохранит ссылку, и в какой момент он ее отпустит?

Еще раз сейчас никак, а как это я реализую или реализую ли вообще вариантов куча.

Твои предложения по текущей ситуации
Твои предложения по текущей ситуации

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

Это не предложение. Это топтание на месте.

Если что-то вам не нравится — ну что ж, это ваше личное дело. Только не говорите потом, что вам ничего не предлагали.

Со ссылкой на что, я стесняюсь спросить? На v? То есть теперь еще и .net-код при каждом обращении к свойству полученного из JS объекта будет обращаться обратно в CEF за данными?

Да. А как мне по твоему методы перенести?
Если мне нужно копию, то я уё прекрасно сериализую, но вот методы я не скопирую

Я же говорю: remoting чистой воды, с двусторонними прокси. Вам рассказать, чем это закончилось?

remoting твой любимы out process.
COM на .Net до сих пор живой, а там те же самые прокси
remoting твой любимы out process.

Кстати, нет.


COM на .Net до сих пор живой, а там те же самые прокси

Много что "до сих пор живо", только это же не повод им пользоваться.

Угу, бедные 1С ники переходя на 64 сразу дико матерятся, а на Linux кстати из-за это и не переходят.
Есть куча компонентов на 1С. В том числе и моя Использование сборок .NET в 1С 7.x b 8.x. Создание внешних Компонент.

А работать чере Вэб или http сервисы очень не удобно, кстати за что ратуешь ты.

Угу, бедные 1С ники переходя на 64 сразу дико матерятся, а на Linux кстати из-за это и не переходят.

Если честно, проблемы 1С-ников меня волнуют мало. Статья, вроде как, не про 1С.


А работать чере Вэб или http сервисы очень не удобно, кстати за что ратуешь ты.

Кому неудобно? Почему именно неудобно?

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

А я и не говорю, что он никому не нужен.


Вэб или http сервисы значительнее неудобнее COM.

Правда? Вызовите COM из любого браузера. Удалось? Вызовите COM на любом мобильном устройстве. Удалось?


(масштабирование? роутинг? прочие прелести?)


При этом с СОМ легко справится любой 1С ник.

Повторюсь, проблемы 1C-ников меня волнуют мало, топик вроде как не про 1С.


А вот писать Вэб или http севисы на других языках могут единицы.

Да ладно вам, писать веб-сервисы легко и приятно.

Вот а как раз и предлагаю замену COM на линукс.
И какие проблемы с масштабированием на локальном компьютере?
А меня и их очень волнуют.
Поверь 1С никам это доставляет большие проблемы. Таких как я очень мало.

Опять же я тебя не заставляю пользоваться моим продуктом.
Вот а как раз и предлагаю замену COM на линукс.

… в одном очень конкретном сценарии. Спасибо, но нет.


И какие проблемы с масштабированием на локальном компьютере?

А вы где-то оговорились уже, что "вебсервисы неудобнее COM на локальном компьютере"?


Поверь 1С никам это доставляет большие проблемы.

Это повод перестать быть "1С-ником" и начать быть программистом.

Еще раз причем масштабирование и локальный компьютер?
Зачем мне вообще вебсервисы если я все выполняю локально?

Я 1С ник и программирую на многих языках.
Зачем мне вообще вебсервисы если я все выполняю локально?

Низачем (если не считать Interoperability). Но вы зачем-то сравниваете именно с вебсервисами.


Я 1С ник и программирую на многих языках.

Ну так почему тогда проблема написать сервер на другом языке?

Это ты все ратуешь за вэб и HTTP сервисы/
Ну так я и пушу на TypeScript,C++
,C#
Это ты все ратуешь за вэб и HTTP сервисы/

Нет, я ратую за разумное применение технологий по месту.

и я даже не буду спрашивать, что такое «ws» в этой паре


ws = WebSockets, если что. Можно и другие способы организовать взаимодействие, но я имел в виду именно связку что приложение выполняется локально. Desktop еще не настолько умер.
Я про SignalR говорил. Ws это просто разновидность этого протокола.
Приложение на чем? Что будет UI для Linux и яблока?
Еще раз я просто предоставил свой продукт. Я его никому не навязываю.
Кто то найдет интересного в Proxy Promise для TS, кому то понравится CEF, кто то может использовать .Net классы из натива. Там много чего можно подчерпнуть.
Я про SignalR говорил. Ws это просто разновидность этого протокола.

Вообще-то, нет.

http://metanit.com/sharp/mvc5/16.1.php
Транспорт передачи данных
Для обмена данными между клиентом и сервером SignalR использует тот способ передачи или тот транспорт, который наиболее подходит к данной ситуации. Однако разработчики могут переопределить способ передачи. SignalR предоставляет следующие типы технологий для взаимодействия сервера и клиента:
WebSockets
Server-sent events
Forever Frames
Long polling

Вы, видимо, не понимаете разницы между "разновидность протокола" и "одна из используемых технологий". SignalR — это вообще не протокол.

Я говорил про то, что он используе разные протоколы в том числе и ws.
Да и определение лучшего протокола это протокол.

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


Но не суть, к теме это отношения не имеет.

С тобой тут не только запутаешься. Я и работаю и тебе отвечаю.

… так вот локально — не обязательно в одном процессе.

Кстати мне часто по работе приходится работать с торговым оборудованием, разными компонентами. Для решения задач можно пойти 2 путями. На основании нужных классов сделать класс обертку и вызывать его из 1с.
Второй путь это использовать эти классы напрямую.
Второй вариант в большинстве случаев предпочтительнее. Мне проще подправить код 1С приспосабливая к различным вариантам, чем городить универсальную обертку на Net.
Это как раз из аналогии http\ws.

Но опять же в самом начале статьи я написал, что это мало кому интересно, хотя это мало чем отличается от использования классов JS
Для решения задач можно пойти 2 путями.

Неа, это вы знаете только два пути решения этой задачи. Например, можно для торгового оборудования выставить адаптер, который уже вызывать из любой заинтересованной системы. Уж если у вас есть возможность поставить на железку ваше приложение, то и адаптер для другой железки всегда можно поставить (это если его из коробки нету).

А зачем мне это делать, если мне проще вызвать напрямую. А с http\ws тебе нужно городить плагин ничем не отличающегося от моей компоненты, либо отсылать данные на сервер и через SignalR оповещать о событии,
А зачем мне это делать, если мне проще вызвать напрямую.

Потому что попробуйте вызвать "напрямую" из чистого браузера, тогда и поговорим.


либо отсылать данные на сервер и через SignalR оповещать о событии,

Бинго! и теперь мне даже не надо подключать весы к торговой станции!

Куча плагинов для этого есть. 1С например позволяет создавать свои обработчики.

А из чистого браузера никак не получится. Я всего навсего предлагаю рассмотреть альтернативу. Только и всего.
А из чистого браузера никак не получится.

И давно из чистого браузера нельзя обратиться к HTTP-серверу?

При чем тут HTTP-серверу, я говорил про оборудование подключенное к компьютеру

При том, что адаптер для подключенного оборудования может быть реализован в виде локального http-сервера. Это если нам надо иметь максимально широкие возможности подключения к нему из кода.

Угу теперь остается только делать адаптер, http сервис итд.
Кстати так и делают в Linux/ Только адаптер на Windows. Это как штаны через голову. Заранее спасибо за минус.
Угу теперь остается только делать адаптер, http сервис итд.

Ну да, обычная работа программиста. Вопрос того, насколько легко это потом использовать (и это — основной вопрос).

Для меня как раз легче использовать мою разработку. Но у каждого свои предпочтения.
На самом деле, что касается 1С, то там на вопрос почему вы не используете мою разработку отвечают, что ты же не 1С.

Я ни кто, и зовут меня ни как. Но тот же Electron будут с удовольствием использовать ибо…
«Нет времени» — не пиши, напишешь, когда будет время собраться и написать статью.
Еще раз прошу прощения у всех читателей за русльшь. Но я попытаюсь оправдаться.
На самом деле этому проекту уже несколько лет. Ноги растут отсюда Использование сборок .NET в 1С 7.x b 8.x. Создание внешних Компонент

Но сама разработка велась еще раньше. При этом от этого я никаких дивидентов не получаю. В основном тычки «зачем это нужно», но есть конечно и благодарности, но их немного. При этом реально легко можно расширить возможности для 1С. Но и 1С это не нужно. Мои разработки Но я не опускаю руки. Днем программирую на 1С, а вечером еще на C#,C++ и TypeScript.
При этом катастрофически не высыпаюсь. Но в разработке много интересного и я хочу поделиться этим с коллегами, надеясь, что коллеги простят мне мой руслиш и войдут в моё нелегкое положение. При этом я прекрасно понимаю, что получу кучу минусов. Но надеюсь, что за мои труды мне полагается небольшое снисхождение.
Статья очень интересная, не падай духом))Много полезного материала. Но думаю людям не совсем понятно, как и для чего этого нужно. Я думаю, если бы в картинках показать как связать тот же Electron+.NET, то было бы намного наглядней)
Огромное спасибо за поддержку. Проблема в том, что я один. У меня огромное время уходит на изучение C++, TypeScrpt и еще кучи вещей что бы связать JS-native-Net.При этом я работаю программистом 1С. Все это в свободное от работы время. Плюс я плохой художник. Выложил программы, но на данный момент их скачали всего 4 человека.
Тема интересная, не опускайте руки — пишите и держите в уме, что кому-то (нам) это читать:)
Спасибо! Я стараюсь. Сейчас переписываю эвенты на инглиш
Проблема в том, что я завожусь, не сплю итд пока не сделаю, то что наметил. Поэтому для меня очень важен сон и душевное спокойствие, иначе я вообще не напишу статью. Еще раз прошу прощения. Но кроме руслиша, там много всего интересного. Что кроме руслиша тебе не понравилось?
Вот тут в соседней теме по Xamarin люди делятся ссылками Avalonia.A multi-platform .NET UI framework. It can run on Windows, Linux, Mac OS X, iOS and Android.
Вообще, судя по комментами, то больше распространена практика, когда бизнес логику пишут кроссплатформенно, а гуи под каждую платформу по гайдлайнам.
Про авалонию я знаю. Она еще в альфе. Ну так и я предлагаю ГУИ писать на Angular 2, на кроссплатформеном .Net Core. Скоро выйдет NetStandard 2 и .Net Core 1.2 и возможностей будет значительно больше.
Она еще в альфе.

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

Ну так и я предлагаю ГУИ писать на Angular 2

Имеется ввиду, что сам интерфейс различается даже между iOS и android, а с десктопом и подавно, всеравно не получится сделать ГУИ, чтобы везде было хорошо. Для iOS будешь делать одну форму, для Linux Desktop другую.
Ну так CEF браузер то тем и хорош, что он и для декстопов один и тот же
Chromium Embedded Framework (CEF) Automated Builds

Что касается моей разработки, то это наколеночная поделка, но она работает. В том числе и на 1С

Использование сборок .NET в 1С 7.x b 8.x. Создание внешних Компонент

и на .Net Core

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

Еще добавлю. Я 1С ник. А там есть и тонкий и толстый клиент и вэб клиент. Вэб клиент самый ущербный, но на него уходит куча кода Про веб-клиент 1С

Я сторонник тонкого клиента. При этом код который сделан под WPF и UWP можно легко перенести на Angular 2 стремительно развивается. Но кто такой я?
Only those users with full accounts are able to leave comments. Log in, please.

Articles