Меня все спрашивают — «Зачем это нужно?». На что, я гордо отвечаю — «Я в 1С использую для доступа к торговому оборудованию, к Вэб-сервисам по ws-протоколам, готовым компонентам. 1С, Linux, Excel, Word, OpenXML,ADO и Net Core. Кроме того, сделаю передачу JS объектов на сторону .Net с использованием через DynamicObject.

Можно сделать определенную конфигурацию CEF для всех платформ и можно делать кросспалатформенные декстопные приложения. Как аналог Electron. .Net Core развивается и можно достаточно легко перевести приложения под WPF и UWP на Angular 2» сделав описание классов и использовать IntelliSense при кодировании на TypeScript.

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

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

В нем куча сахара и показывает все проблемы. Сразу прошу прощения за Руслиш. Я очень стараюсь, но у меня на нем куча примеров, а времени очень мало.

 // Метод расширения
    //IConfiguration WithDefaultLoader(this IConfiguration configuration, Action<LoaderSetup> setup = null, IEnumerable<IRequester> requesters = null);
    var config = Configuration.Default.WithDefaultLoader();
    // Устанавливаем адрес страницы сайта
    var address = "https://en.wikipedia.org/wiki/List_of_The_Big_Bang_Theory_episodes";
    // загружаем страницу и разбираем её
 
    //Метод расширения
    //Task<IDocument> OpenAsync(this IBrowsingContext context, string address);
    var document = BrowsingContext.New(config).OpenAsync(address).Result;
    // Используем CSS селектор для получения строк таблицы с классом  
    var rowSelector = "tr.vevent";
    var Строки = document.QuerySelectorAll<IHtmlTableRowElement>(rowSelector);
    foreach (var str in Строки)

На TypeScript это выглядит так:

            let Net = NetObject.NetWrapper;
            let $$ = NetObject.FlagDeleteObject; // Символ для признака удаления при вызове объекта как метода

            // Загрузим сборку AngleSharpж
            let СборкаAngleSharp = Net.Сборка("AngleSharp");
            // Получим из неё используемые типы
            let Configuration = СборкаAngleSharp.GetType("AngleSharp.Configuration");
            let BrowsingContext = СборкаAngleSharp.GetType("AngleSharp.BrowsingContext");
            let HtmlParser = СборкаAngleSharp.GetType("AngleSharp.Parser.Html.HtmlParser");
            let IHtmlTableRowElement = СборкаAngleSharp.GetType("AngleSharp.Dom.Html.IHtmlTableRowElement");
            let ApiExtensions = СборкаAngleSharp.GetType("AngleSharp.Extensions.ApiExtensions");

            let Default = Configuration._Default;
            var config = Default.WithDefaultLoader();
            // Устанавливаем адрес страницы сайта
            var address = "https://en.wikipedia.org/wiki/List_of_The_Big_Bang_Theory_episodes";
            // загружаем страницу и разбираем её

            let Context = BrowsingContext.New(config);

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

            // Используем CSS селектор для получения строк таблицы с классом  
            let rowSelector = "tr.vevent";

            // Для дженериков пока не сделал поиск в расширениях поэтому вместо
            //let rows = document.QuerySelectorAll([IHtmlTableRowElement], rowSelector);
           
            // используем метод расширения явно
            //IEnumerable < TElement > QuerySelectorAll<TElement>(this IParentNode parent, string selectors) where TElement : IElement;
             let rows = ApiExtensions.QuerySelectorAll([IHtmlTableRowElement], document, rowSelector);
         
            // можно и так вызвать, но нужно обыграть все варианты
            //let rows = document.QuerySelectorAll(rowSelector);

// Пройдемся по нужным строкам распарсенной таблицы
            for (let row of rows) {
                let Cells = row._Cells;
                let i = 0;
                let данныеСайта = new ДанныеСайта();
                this.ResultParse.push(данныеСайта);
// Загрузим данные ячеек в поля объекта ДанныеСайта
                for (let Cell of Cells) {
 // Нужно дождаться окончания итератора, что бы освободить ссылку на итератор
                    if (i < 8)                        {
                    данныеСайта[this.Colums[i]] = Cell._TextContent;
                    Cell($$); // Удалим ссылку из хранилища объектов 
                    i++;
                    }
                }
                Cells($$);
                row($$);
            }
            rows($$);

            // Удалим вручную испльзуемые объекты
            NetObject.DeleteNetObjets(СборкаAngleSharp, Configuration, BrowsingContext, HtmlParser, IHtmlTableRowElement, ApiExtensions, Default, config, Context, document); 
            alert("Количество элементов в хранилище "+Net.КоличествоЭлементовВХранилище());

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

let Default = Configuration._Default;

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

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

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

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

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

Cells(NetObject.FlagDeleteObject);
для уменьшения писанины
Cells($$);

По скорости вызовов на моем Intel Core i3-2120 CPU 3.3 GHz.

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

Что в общем-то вполне приемлемо.

Приведу еще небольшой пример.

 public class Тестовый
    {
       public string СвойствоОбъекта { get; set; }
       public  Тестовый(string СвойствоОбъекта)
            {
            this.СвойствоОбъекта = СвойствоОбъекта;
            }
 public object ПолучитьExpandoObject()
        {

            dynamic res = new ExpandoObject();
            res.Имя = "Тест ExpandoObject";
            res.Число = 456;
            res.ВСтроку = (Func<string>)(() => res.Имя);
            res.Сумма = (Func<int, int, int>)((x, y) => x + y);

            return res;
        }
     }

На 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 из неуправляемого кода. Или аналог IDispatch на Linux. Через CEF встраиваем нужные методы:

   declare var window: WindowInterface;
    export interface WindowInterface {
    CallNetMethod(Id: number, MethodName: string, args?: any[]): any;// Вызов метода
    CallNetDelegate(Id: number, args?: any[]): any; // Вызов делегата
    CallNetPropertySet(Id: number, PropertyName: string, value: any): void; // Установка свойства
    CallNetPropertyGet(Id: number, PropertyName: string): any; // Получение значения свойства
    DeleteNetObject(Id: number): void; // Освободить ссылку на объект со стороны .Net
    // Асинхронный вызов метода возвращающий Task или Task<T>
    CallAsyncNetObjectFunction(Id: number, MethodName: string, TaskId: string, args?: any[]): any; 
    // Регистрация метода на стороне CEF, для установки результата Promise 
    RegisterCallBacks(SetAsyncResult: (Successfully: boolean, TaskId: string, result: any) => void): void; 
    // Вызов дженерик метода с указанием типов аргументов
    CallNetObjectGenericFunction(Id: number, MethodName: string, types: any[], args?: any[]): any;
    // Вызов итератора IEnumerator MoveNext на стороне .Net
    IteratorNext(Id: number): any;
}

Для удобного использования этих методов создадим класс прокси с Target гибридного типа:

export interface NetObjectinterface {
    (): void;
    Id: number;
    isNetObject: boolean;
    IsAsyncCall?: boolean;
    CallAsProp(target: NetObject, name: any): ResultCallAsProp;
    Execute: (target: NetObject, name: any, args: any[]) => any;

}

Target должен быть функцией для возможности использования new и (). Теперь нам понадобится Handler:

export var NetObjectHandler: ProxyHandler<NetObjectinterface> = {
    get: (target, name: any) => {
// Вызывается как PropertyGet как для свойств так и методов
// Что бы их разделить  свойства начинаются с "_"

        let res = target.CallAsProp(target, name);
        if (res.Successfully)
            return res.result;

        return (...args: any[]) => {
            return target.Execute(target, name, args);
        }

    },
    set: function (target, prop, value, receiver) {
        return NetObject.SetPropertyValue(target, prop, value, receiver);
    },

    apply: (target, that, args) => {
        if (args.length == 1) {
            var param = args[0];
            if (param === NetObject.FlagGetObject)
                return target;
            else if (param === NetObject.FlagDeleteObject) {
                window.DeleteNetObject(target.Id);
                return undefined;
            }
        }

        NetObject.SetArgs(args);
        let res = window.CallNetDelegate(target.Id, args)
        return NetObject.WrapResult(res, true);
    },

    construct: (target, argumentsList, newTarget) => {
// Используем метод на стороне Net 
// object Новый(object Тип, params object[] argOrig)
        NetObject.SetArgs(argumentsList);
        argumentsList.unshift(target);
        let res = window.CallNetMethod(0, "Новый", argumentsList);
        return NetObject.WrapResult(res, true);

    }
}

Ну и понадобится сам Target:

function getNetObject(id: number): NetObjectinterface {
    let netObject = <NetObjectinterface>function (start: number) { };
    netObject.Id = id;
    netObject.isNetObject = true;
    netObject[NetObject.isNetclass] = true;
    netObject.Execute = NetObject.Execute;
    netObject.CallAsProp = NetObject.CallAsProp;
    return netObject;
}

Для обертки результата из CEF используется:

static WrapResult(value: any, ReturnProxy: boolean = false): any {
        if (typeof value == "object") {
            if ("IsNetObject" in value) {
                let res = getNetObject(value.Id);
                if (ReturnProxy)
                    return new Proxy(res, NetObjectHandler);
                else
                    return res

            }


        }
        return value;
    }

Что касается асинхронных методов то они работают через два метода:

static GetPromise(Target: NetObjectinterface, name: any, args: any[]) {

        let key = window.CallNetMethod(0, "GetUniqueString");
        let promise = new Promise((resolve, reject) => {
            NetObject.PromiseDictioanary.set(key, { resolve: resolve, reject: reject });
            window.CallAsyncNetObjectFunction(Target.Id, name, key, args);
        });
        return promise;
    }

И при получении асинхронного результата:

 static SetPromiseResult(Successfully: boolean, TaskId: string, result: any) {
        let item = NetObject.PromiseDictioanary.get(TaskId);
        try {

            NetObject.PromiseDictioanary.delete(TaskId);
           // Вот здесь не могу установить результат Proxy с Target function
            //  result = NetObject.WrapResult(result, true);
           // возникает исключение "Не найден then"
            if (Successfully)
                item.resolve(result);
            else
                item.reject(result);
        }

        catch (e) {
            item.reject("ошибка установки асинхронного результата " + e);
            alert("ошибка установки асинхронного результата " + e);
        }
    }

где:

 static PromiseDictioanary = new Map();

Весь код можно посмотреть ниже под спойлером:

Весь код NetProxy
declare var window: WindowInterface;
declare var $_: Symbol;
declare var _$: Symbol;

export interface WindowInterface {
    CallNetMethod(Id: number, MethodName: string, args?: any[]): any;// Вызов метода
    CallNetDelegate(Id: number, args?: any[]): any; // Вызов делегата
    CallNetPropertySet(Id: number, PropertyName: string, value: any): void; // Установка свойства
    CallNetPropertyGet(Id: number, PropertyName: string): any; // Полусение значения свойства
    DeleteNetObject(Id: number): void; // Освободить ссылку на объект со стороны .Net
    // Асинхронный вызов метода возвращающий Task или Task<T>
    CallAsyncNetObjectFunction(Id: number, MethodName: string, TaskId: string, args?: any[]): any; 
    // Регистрация метода на стороне CEF, для установки результата Promise 
    RegisterCallBacks(SetAsyncResult: (Successfully: boolean, TaskId: string, result: any) => void): void; 
    // Вызов дженерик метода с указанием типов аргументов
    CallNetObjectGenericFunction(Id: number, MethodName: string, types: any[], args?: any[]): any;
    // Вызов итератора IEnumerator MoveNext на стороне .Net
    IteratorNext(Id: number): any;
}

class ResultCallAsProp {
    constructor(public Successfully: boolean, public result?: any) { };
}
export interface NetObjectinterface {
    (): void;
    Id: number;
    isNetObject: boolean;
    IsAsyncCall?: boolean;
    CallAsProp(target: NetObject, name: any): ResultCallAsProp;
    Execute: (target: NetObject, name: any, args: any[]) => any;

}

export var NetObjectHandler: ProxyHandler<NetObjectinterface> = {
    get: (target, name: any) => {


        let res = target.CallAsProp(target, name);
        if (res.Successfully)
            return res.result;

        return (...args: any[]) => {
            return target.Execute(target, name, args);
        }


    },
    set: function (target, prop, value, receiver) {
        return NetObject.SetPropertyValue(target, prop, value, receiver);
    },

    apply: (target, that, args) => {
        if (args.length == 1) {
            var param = args[0];
            if (param === NetObject.FlagGetObject)
                return target;
            else if (param === NetObject.FlagDeleteObject) {
                window.DeleteNetObject(target.Id);
                return undefined;
            }
        }

        NetObject.SetArgs(args);
        let res = window.CallNetDelegate(target.Id, args)
        return NetObject.WrapResult(res, true);
    },

    construct: (target, argumentsList, newTarget) => {

        //  var res = NetObject.GetNetObject(5);
        //  return new Proxy(res, NetObjectHandler)
        NetObject.SetArgs(argumentsList);
        argumentsList.unshift(target);
        let res = window.CallNetMethod(0, "Новый", argumentsList);
        return NetObject.WrapResult(res, true);

    }


}

function getNetObject(id: number): NetObjectinterface {
    let netObject = <NetObjectinterface>function (start: number) { };
    netObject.Id = id;
    netObject.isNetObject = true;
    netObject[NetObject.isNetclass] = true;
    netObject.Execute = NetObject.Execute;
    netObject.CallAsProp = NetObject.CallAsProp;
    return netObject;
}

function GetNetProxy(): any {
    let res = getNetObject(0);
    if (NetObject.FlagFirstLoad) {
        try {
            window.RegisterCallBacks(NetObject.SetPromiseResult);

        }
        catch (e) {
            // alert("ошибка " + e);
        }

        NetObject.FlagFirstLoad = false;
    }

    return new Proxy(res, NetObjectHandler);

}
export class NetObject {
    static GetNetObject(id: number) { return getNetObject(id); }
    static isNetclass = Symbol();
    static IsAsyncCall = Symbol();
    static FlagGetObject = Symbol();
    static FlagDeleteObject = Symbol();
    static FlagFirstLoad = true;
    static NetWrapper = GetNetProxy();

    static PromiseDictioanary = new Map();
    static GetIterator(target: NetObjectinterface): any {
        return function () {
            let IdIterator = window.CallNetMethod(0, "GetIterator", [target]).Id;

            return {
                next: function () {

                    let value = window.IteratorNext(IdIterator);
                    if (value === undefined) {
                        return { value: undefined, done: true };

                    } else
                        return { value: NetObject.WrapResult(value, true), done: false }

                }
            }


        }
    }


    static WrapResult(value: any, ReturnProxy: boolean = false): any {
        if (typeof value == "object") {
            if ("IsNetObject" in value) {
                let res = getNetObject(value.Id);
                if (ReturnProxy)
                    return new Proxy(res, NetObjectHandler);
                else
                    return res

            }


        }
        return value;
    }

    static WrapObject(value: any): any {
        if (typeof value == "function") {
            if (NetObject.isNetclass in value)
                return new Proxy(value, NetObjectHandler);
        }
    }

    static GetPropertyValue(target: NetObjectinterface, name: any): any {
        let res = window.CallNetPropertyGet(target.Id, name);
        return NetObject.WrapResult(res, true);

    }

    static SetPropertyValue(target: NetObjectinterface, prop: any, value: any, receiver: any): any {
        let res = window.CallNetPropertySet(target.Id, prop, NetObject.GetTarget(value));
        return true;

    }

    static CallAsProp(Target: NetObjectinterface, name: any): ResultCallAsProp {
        if (name === Symbol.iterator) {
            return new ResultCallAsProp(true, NetObject.GetIterator(Target));
        }

        if (name === Symbol.toPrimitive) {
            return new ResultCallAsProp(true, () => { return `Id= ${Target.Id}, isNetObject= ${Target.isNetObject}` });
        }
        if (name.startsWith('_')) {

            return new ResultCallAsProp(true, NetObject.GetPropertyValue(Target, name.substring(1)));

        }

        if (name === "async") {

            let res = getNetObject(Target.Id);

            res.Execute = NetObject.ExecuteAsync;
            res.CallAsProp = NetObject.CallAsPropAsync;
            return new ResultCallAsProp(true, new Proxy(res, NetObjectHandler));
        }

        return new ResultCallAsProp(false);
    }

    static CallAsPropAsync(Target: NetObjectinterface, name: any): ResultCallAsProp {


        return new ResultCallAsProp(false);
    }

    static GetPromise(Target: NetObjectinterface, name: any, args: any[]) {

        let key = window.CallNetMethod(0, "GetUniqueString");
        let promise = new Promise((resolve, reject) => {
            NetObject.PromiseDictioanary.set(key, { resolve: resolve, reject: reject });
            window.CallAsyncNetObjectFunction(Target.Id, name, key, args);
        });
        return promise;
    }

    static GetTarget(obj: any): any {
        if (typeof obj == "function") {
            if (NetObject.isNetclass in obj)
                return obj(NetObject.FlagGetObject);


        }
        return obj;
    }

    static SetArgs(args: any[]) {
        for (let i in args) {
            let obj = args[i];
            if (typeof obj == "function") {
                if (NetObject.isNetclass in obj)
                    args[i] = obj(NetObject.FlagGetObject);


            }

        }
    }


    static SetPromiseResult(Successfully: boolean, TaskId: string, result: any) {
        let item = NetObject.PromiseDictioanary.get(TaskId);
        try {

            NetObject.PromiseDictioanary.delete(TaskId);
            //  result = NetObject.WrapResult(result, true);
            if (Successfully)
                item.resolve(result);
            else
                item.reject(result);
        }

        catch (e) {
            item.reject("ошибка установки асинхронного результата " + e);
            alert("ошибка установки асинхронного результата " + e);
        }
    }

    static CheckGenericMethod(args: any[]): any {

        var argsCount = args.length;

        if (argsCount > 0 && args[0] instanceof Array) {
            var types = args[0].slice();
            NetObject.SetArgs(types);

            var args2 = args.slice(1);
            NetObject.SetArgs(args2);
            return { IsGeneric: true, types: types, args: args2 }
        }

        return { IsGeneric: false };

    }
    static Execute(Target: NetObjectinterface, name: any, args: any[]) {

        let res = undefined;
        let chek = NetObject.CheckGenericMethod(args);

        if (chek.IsGeneric) {
            res = window.CallNetObjectGenericFunction(Target.Id, name, chek.types, chek.args);

        }
        else {
            NetObject.SetArgs(args);

            res = window.CallNetMethod(Target.Id, name, args);
        }

        return NetObject.WrapResult(res, true);
    }

    static ExecuteAsync(Target: NetObjectinterface, name: any, args: any[]) {


        let res = undefined;
        let chek = NetObject.CheckGenericMethod(args);

        if (chek.IsGeneric) {
            let Target0 = getNetObject(0);
            let task = window.CallNetObjectGenericFunction(Target.Id, name, chek.types, chek.args);
            res = NetObject.GetPromise(Target0, "ReturnParam", [getNetObject(task.Id)]);
            window.DeleteNetObject(task.Id);

        }
        else {
            NetObject.SetArgs(args);

            res = NetObject.GetPromise(Target, name, args);
        }

        return res;
    }

    static New(Target: NetObjectinterface, name: any, args: any[]): any {
        NetObject.SetArgs(args);
        var res = window.CallNetMethod(0, "Новый", args);
        return NetObject.WrapResult(res, true);
    }

    static DeleteNetObjets(...args: any[]) {

        for (let item of args)
            item(NetObject.FlagDeleteObject);
    }


}


Прошу прощение за моё незнание С++. Но, делать было нужно сейчас, а я на нем не пишу.
Не смог прикрутить Dev Tools к CefSimple:

Код CEF обертки для обмена между JS и .Net Core
#include "include/CEF_V8.H"
#include "ManagedDomainLoader.h"
#include "CefV8HandlersForNet.h"

#include "types.h"
#include "NetConverter.h"


#include "include/base/cef_bind.h"
#include "include/wrapper/cef_closure_task.h"
#include <thread>
#include "include/base/cef_platform_thread.h"
namespace NetObjectToNative{

	BaseClassForNetHandlers::BaseClassForNetHandlers(ManagedDomainLoader* mD)
	{
		this->mD = mD;
	}

	 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 CallAsyncNetObjectFunction::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();
		 wstring TaskId = arguments[2]->GetStringValue().ToWString();

		 CefRefPtr<CefV8Value> params;

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


			 params = arguments[3];

			 if (!params->IsArray())
			 {
				 exception = CefString(L"Для вызова асинхронного метода 4 параметр должен быть массивом");
				 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);
		 bool res = mD->pCallAsyncFunc(Target, MethodMame.c_str(), this->cfn, TaskId.c_str(), 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;
	 }

	//============================ Call Generic Function

	 bool CallNetObjectGenericFunction::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;
		 NetObjectToNative::tVariant* ParamsTypes = nullptr;

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

		 CefRefPtr<CefV8Value> params;
		 CefRefPtr<CefV8Value> types= arguments[2];
		 size_t  typesCount= types->GetArrayLength();


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


			 params = arguments[3];

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

			 }
			 argCount = params->GetArrayLength();


		 }

		 
		 savedstrings.reserve(argCount+ typesCount);
		 ParamsTypes = new NetObjectToNative::tVariant[typesCount];
		 for (size_t i = 0; i < typesCount; ++i)
		 {

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


		 if (argCount > 0)
		 {
			
			 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->pCallAsGenericFunc(Target, MethodMame.c_str(), &RetVal, ParamsTypes, typesCount, Params, argCount, &Error);

		 if (res)
		 {

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

		 if (Params) delete[] Params;
		 delete[] ParamsTypes;

		 return true;
	 }


	 //===================== CallNetDelegate

	 bool CallNetDelegate::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();
		

		 CefRefPtr<CefV8Value> params;

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


			 params = arguments[1];

			 if (!params->IsArray())
			 {
				 exception = CefString("Для вызова делегата  2 параметр должен быть массивом");
				 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->pCallAsDelegate(Target, &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;
	 }

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


		 const size_t argumentsCount = arguments.size();

		 if (argumentsCount != 3)
		 {


				 exception = CefString(L"Для PropertySet должно быть 3 параметра");
				 return true;

			}
			 
		 vector<wstring> savedstrings;


		 int Target = arguments[0]->GetIntValue();
		 wstring PropertyName = arguments[1]->GetStringValue().ToWString();
		 CefRefPtr<CefV8Value> value = arguments[2];

			 
			 savedstrings.reserve(1);
			 NetObjectToNative::tVariant Param;
			
			 NetObjectToNative::ConvertCEFtoNet(value, &Param, savedstrings);
			 


		 wchar_t*  Error = nullptr;
	
		 bool res = mD->pSetPropVal(Target, PropertyName.c_str(), &Param, &Error);

		 if (!res)
		 {
			 if (Error)
			 {
				 exception = CefString(std::wstring(Error));
				 delete Error;
			 }
			 else 
				 exception = CefString(L"Ошибка при установке свойства"+ PropertyName);
			
		 }

		

		 return true;
	 }

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


		 const size_t argumentsCount = arguments.size();

		 if (argumentsCount != 1)
		 {
			 exception = CefString(L"Для DeleteObject Должно быть 1 параметра");
			 return true;
		 }

		 CefRefPtr<CefV8Value> value = arguments[0];
		 
		 
		 mD->pDeleteObject(value->GetIntValue());

		

		 return true;
	 }

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


		 const size_t argumentsCount = arguments.size();

		 if (argumentsCount != 1)
		 {
			 exception = CefString(L"Для IteratorNext Должно быть 1 параметра");
			 return true;
		 }

		 CefRefPtr<CefV8Value> value = arguments[0];
		 wchar_t*  Error = nullptr;
		 NetObjectToNative::tVariant RetVal;

		bool res= mD->pIteratorNext(value->GetIntValue(),&RetVal, &Error);
		if (res)
		{
			retval = NetObjectToNative::ConvertNetToCef(&RetVal, true);

		}
		else
		{
			retval = CefV8Value::CreateUndefined();
			if (Error)
			{
				exception = CefString(std::wstring(Error));
				delete Error;
			}

		}
		 return true;
	 }

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


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

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

		 bool res = mD->pGetPropVal(Target, PropertyName.c_str(), &RetVal,&Error);

		 if (!res)
		 {
			 if (Error)
			 {
				 exception = CefString(std::wstring(Error));
				 delete Error;
			 }
			 else
				 exception = CefString(L"Ошибка при установке свойства " + PropertyName);

		 }
		 else
			 retval = NetObjectToNative::ConvertNetToCef(&RetVal, true);



		 return true;
	 }

	 void SetHandlerToContex(CefRefPtr<CefV8Handler> Handler, CefRefPtr<CefV8Value> object, const char* MetodName)
	 {

		 CefRefPtr<CefV8Value> CallNetObject = CefV8Value::CreateFunction(MetodName, Handler);

		 // Add the "myfunc" function to the "window" object.
		 object->SetValue(MetodName, CallNetObject, V8_PROPERTY_ATTRIBUTE_NONE);
	 }

	 void ContextForNetHandlers::OnContextCreated(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefV8Context> context)
	 {
		 this->context = context;
		 // Retrieve the context's window object.
		 CefRefPtr<CefV8Value> object = context->GetGlobal();
		 NetObjectToNative::ManagedDomainLoader* mD = NetObjectToNative::ManagedDomainLoader::InitManagedDomain(L"c:\\Program Files\\DNX\\runtimes\\dnx-coreclr-win-x86.1.0.0-rc1-update1\\bin\\", L"", L"");

		 //=========== CallNetMethod =======================================================
		 SetHandlerToContex(new CallNetObjectFunction(mD), object, "CallNetMethod");
		 //=========== CallNetDelegate =======================================================
		 SetHandlerToContex(new CallNetDelegate(mD), object, "CallNetDelegate");
		 //=========== PropertySet =======================================================
		 SetHandlerToContex(new CallNetObjectPropertySet(mD), object, "CallNetPropertySet");
		 //=========== PropertyGet =======================================================
		 SetHandlerToContex(new CallNetObjectPropertyGet(mD), object, "CallNetPropertyGet");
		 //=========== PropertyGet =======================================================
		 SetHandlerToContex(new DeleteNetObject(mD), object, "DeleteNetObject");
		 //=========== SetCallBacks =======================================================
		 SetHandlerToContex(new SetCallBacks(mD, this, object), object, "RegisterCallBacks");
		 //============ CallAsyncNetObjectFunction ================================
		 SetHandlerToContex(new CallAsyncNetObjectFunction(mD, this), object, "CallAsyncNetObjectFunction");
		 //============ CallNetObjectGenericFunction ================================
		 SetHandlerToContex(new CallNetObjectGenericFunction(mD), object, "CallNetObjectGenericFunction");
		 //============ IteratorNext ================================
		 SetHandlerToContex(new IteratorNext(mD), object, "IteratorNext");

	 }

	

	 
	 void ContextForNetHandlers::AsyncCalBack(const wchar_t* TaskID, bool Successfully, tVariant* ReturnValue)
	 {
		

		 if (!CefCurrentlyOn(TID_RENDERER)) {
			 // Execute on the UI thread.
			// CefPostTask(TID_UI, base::Bind(&AsyncCalBack2, TaskID, Successfully,ReturnValue, CallbackContext));
			 CefPostTask(TID_RENDERER, base::Bind(&SetCallBacks::AsyncCalBack, this->scb, TaskID, Successfully, ReturnValue));
			 return;
		 }

		 scb->AsyncCalBack(TaskID, Successfully, ReturnValue);
	 }

	 //==================== Set CallBacs
	 bool SetCallBacks::Execute(const CefString& name,
		 CefRefPtr<CefV8Value> object,
		 const CefV8ValueList& arguments,
		 CefRefPtr<CefV8Value>& retval,
		 CefString& exception) {

		    this_id = std::this_thread::get_id();
			 if (arguments.size() == 1 && arguments[0]->IsFunction()) {
				 AsyncMetodCall = arguments[0];
				 CallbackContext = CefV8Context::GetCurrentContext();
				 cfn->scb = this;

				 /*CefV8ValueList args;
				 args.push_back(CefV8Value::CreateBool(true));
				 args.push_back(CefV8Value::CreateString(L"Первый"));
				 args.push_back(CefV8Value::CreateString(L"Второй"));

				 if (AsyncMetodCall->ExecuteFunctionWithContext(CallbackContext, globalObj, args)) {
					
				 }*/
				
				 return true;
			 }
		

		 return true;

	 }

	 void SetCallBacks::AsyncCalBack(const wchar_t* TaskID, bool Successfully, tVariant* ReturnValue)
	 {
		 CefV8ValueList args;
		 
		 std::thread::id Curr_id = std::this_thread::get_id();
		 if (this_id != Curr_id)
		 {
		 }

		 if (CallbackContext.get() && CallbackContext->Enter()) {

			 args.push_back(CefV8Value::CreateBool(true));

			 args.push_back(CefV8Value::CreateString(TaskID));
			 delete[] TaskID;

			 if (ReturnValue==nullptr)
				 args.push_back(CefV8Value::CreateUndefined());
			 else
			 {
			 args.push_back(NetObjectToNative::ConvertNetToCef(ReturnValue, true));
			 delete[] ReturnValue;
			 }
 
			 
			 if (AsyncMetodCall->ExecuteFunctionWithContext(CallbackContext, globalObj, args)) {
				 
			 }
			 CallbackContext->Exit();
		 }
	 }	
}


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

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

Краткое описание содержимого. В каталоге cefsimple\Release\ лежит исполняемый файл с библиотеками и начальной страницей Test.html. В каталоге cefsimple\NetObjectToNative\
лежат все файлы для обмена между CEF и .Net Core. ManagedDomainLoader и ClrLoader отвечают за загрузку .Net Core, получения и передачу методов для обмена данными.

В CefV8HandlersForNet реализованы Хэндлеры для обмена между JS и CEF. В NetConverter конвертация данными между Net и Cef.

В NetObjectToCEF лежат файлы которые реализуют обмен с CEF. В TestDllForCoreClr лежат все используемые примеры для Тестовый.

В файле TestTypeScript\TestTypeScript\app\ лежат файлы ts которые и реализуют Proxy. NetProxy.ts файл реализующий Proxy.

home.component.ts тест с AngleSharp. counter.component.ts различные тесты возможностей. TestSpeed.ts тесты скорости выполнения

Так жепроект без node_modules. установите через вызов в директории TestTypeScript npm install

Суть тестов такова. Запускаете TestTypeScript и CefProgects\cefsimple\Release\cefsimple.exe. На начальной странице можно попробовать тесты на JS. Для использования тестов на TS нужно перейти на сайт который нужно указать в поле ниже «Введите адрес сайта « что бы перейти на него»». Там три теста.

Если хотите компилировать cefsimple. То скачайте отсюда opensource.spotify.com/cefbuilds/index.html 32-разрядный Standard Distribution и замените в директории tests\cefsimple\ сс и h файлы и скопируйте директорию NetObjectToNative.

Для использования VS 2015 введите в корневом каталоге CEF cmake.exe -G «Visual Studio 14»

Для VS 2017 cmake.exe -G «Visual Studio 15 2017».

Спасибо за внимание!
Поделиться с друзьями
-->

Комментарии (255)


  1. ZOXEXIVO
    01.02.2017 21:25
    +1

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


  1. Serginio1
    01.02.2017 22:01
    -1

    На самом деле здесь много интересного. Это и Proxy и Promise для TypeScript.
    Работа с CEF, а так же и Net Core. Кроме того здесь показано как просто можно использовать классы .Net очень близко к кодированию на C#. Здесь очень много информации на любой вкус.


    1. ZOXEXIVO
      01.02.2017 23:06
      +2

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


  1. Serginio1
    01.02.2017 23:20

    Ну у меня и не было цели учить новичков. Главная моя цель показать как можно легко использовать классы .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


    1. lair
      02.02.2017 00:22

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

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


      1. Serginio1
        02.02.2017 10:01

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


        1. lair
          02.02.2017 11:46
          -1

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

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


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

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


          1. Serginio1
            02.02.2017 12:02
            -1

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

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

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


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


            1. lair
              02.02.2017 12:12

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

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


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

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


              1. Serginio1
                02.02.2017 12:43
                -1

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


                1. lair
                  02.02.2017 13:10

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

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


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

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


                  1. Serginio1
                    02.02.2017 13:14

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


                    1. lair
                      02.02.2017 13:16

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


                      1. Serginio1
                        02.02.2017 13:23
                        -1

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


                  1. Serginio1
                    02.02.2017 13:16

                    Кстати а можешь пояснить, за что минус? Проблема в том, что для Linux сейчас не UI. При этом много крика про импортозамещение.


                    1. lair
                      02.02.2017 13:17

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


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


                      1. Serginio1
                        02.02.2017 13:25

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


                        1. lair
                          02.02.2017 13:31
                          +1

                          Можно достаточно легко перевести приложение под WPF на Angular 2

                          Серьезно?


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


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


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


                          1. Serginio1
                            02.02.2017 13:42

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

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


                            1. lair
                              02.02.2017 14:16

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

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


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

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


                              1. Serginio1
                                02.02.2017 14:23

                                Прошу прощения. Wpf здесь лишнее.
                                Спасибо. Просто я сейчас не смогу отвечать. Много работы. Но все равно огромное спасибо!


      1. denismaster
        02.02.2017 11:42

        Я думаю можно таким образом смешать Electron+Angular2, например, как UI, и .NET как бекенда.


        1. lair
          02.02.2017 11:44

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


          1. denismaster
            02.02.2017 11:51

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


            1. lair
              02.02.2017 11:54
              +1

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


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


              1. Serginio1
                02.02.2017 11:58

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

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


                1. lair
                  02.02.2017 11:59

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


                  1. Serginio1
                    02.02.2017 12:04

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


                    1. lair
                      02.02.2017 12:12

                      Они минимальны по сравнению с http\ws.

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


                      1. Serginio1
                        02.02.2017 12:27

                        Еще раз
                        Скорость вызова без 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);
                            }
                        


                        1. lair
                          02.02.2017 12:29
                          +1

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


                          1. Serginio1
                            02.02.2017 12:48

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

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


                            1. lair
                              02.02.2017 13:11

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

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


                              1. Serginio1
                                02.02.2017 13:18

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


                                1. lair
                                  02.02.2017 13:22

                                  Я предлагаю еще вариант использования. Есть альтернатива out-of-process-сервера. Чем это плохо,

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


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

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


                                  1. Serginio1
                                    02.02.2017 13:33

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


                                    1. lair
                                      02.02.2017 14:15

                                      Угу http/ws это надстройка на Tcp/IP.

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


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

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


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

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


                                      1. Serginio1
                                        02.02.2017 14:21

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


                                        1. lair
                                          02.02.2017 14:24

                                          Ну там просто копирование в одном процессе.

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


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

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


                                          1. Serginio1
                                            02.02.2017 14:29

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


                                            1. lair
                                              02.02.2017 14:30

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


                                              1. Serginio1
                                                02.02.2017 14:33
                                                -1

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


                                                1. lair
                                                  02.02.2017 14:38

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


                                                  1. Serginio1
                                                    02.02.2017 14:44
                                                    -1

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


                                                    1. lair
                                                      02.02.2017 14:47

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


                                                      1. Serginio1
                                                        02.02.2017 14:51
                                                        -1

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


                                                        1. lair
                                                          02.02.2017 14:52

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


                                                          1. Serginio1
                                                            02.02.2017 14:57

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


                                                            1. lair
                                                              02.02.2017 15:01

                                                              Я аргументиру это тем, что писать на один процес легче.

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


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


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


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

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


                                                              1. Serginio1
                                                                02.02.2017 15:16
                                                                -1

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

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


                                                                1. lair
                                                                  02.02.2017 15:18

                                                                  Угу чем это отличие от HTTP запроса? Я знаю что за классы я использую.
                                                                  Ну и чем ремотинг от HTTP запроса отличается?

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


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

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


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

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


                                                                  1. mayorovp
                                                                    02.02.2017 15:34

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

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


                                                                    1. lair
                                                                      02.02.2017 15:39

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


                                                                      1. mayorovp
                                                                        02.02.2017 15:48

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


                                                                        1. lair
                                                                          02.02.2017 15:50

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


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


                                                                          1. Serginio1
                                                                            02.02.2017 16:29
                                                                            -1

                                                                            Я же написал в чем отличие
                                                                            Прежде всего видим главные отличия от 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С я могу прикрутить типизацию


                                                                            1. lair
                                                                              02.02.2017 16:43

                                                                              Я же написал в чем отличие

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


                                                                              1. Serginio1
                                                                                02.02.2017 16:48
                                                                                -1

                                                                                Для начала я давал ссылку на Кроссплатформенное использование классов .Net из неуправляемого кода. Или аналог IDispatch на Linux

                                                                                Там расписано как происходит маршалинг


                                                                        1. Serginio1
                                                                          02.02.2017 16:26

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


                                                                          1. lair
                                                                            02.02.2017 16:42

                                                                            Структуры боксятся

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


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

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


                                                                            1. Serginio1
                                                                              02.02.2017 16:45

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


                                                                              1. lair
                                                                                02.02.2017 16:46

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


                                                                                1. Serginio1
                                                                                  02.02.2017 16:57

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

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


                                                                                  1. lair
                                                                                    02.02.2017 16:58

                                                                                    Но на стороне JS нужно вызывать Equals или op_ или compare

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


                                                                                    1. Serginio1
                                                                                      02.02.2017 17:04

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


                                                                                      1. lair
                                                                                        02.02.2017 17:06

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


                                                                                        1. Serginio1
                                                                                          02.02.2017 17:11

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


                                                                                          1. lair
                                                                                            02.02.2017 17:13

                                                                                            Будет объект на стороне Net.

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


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

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


                                                                                            1. Serginio1
                                                                                              02.02.2017 17:22

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

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


                                                                                              1. lair
                                                                                                02.02.2017 17:23
                                                                                                +1

                                                                                                Ну что делать если на стороне JS нет понятия decimal

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


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

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


                                                                                                1. Serginio1
                                                                                                  02.02.2017 17:30
                                                                                                  -2

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

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


                                                                                                  1. lair
                                                                                                    02.02.2017 17:31

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

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


                                                                                                    1. Serginio1
                                                                                                      02.02.2017 17:39

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


                                                                                                      1. lair
                                                                                                        02.02.2017 17:40

                                                                                                        А что делать если JS этого не поддерживает?

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


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

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


                                                                                                        1. Serginio1
                                                                                                          02.02.2017 17:59

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


                                                                                                          1. lair
                                                                                                            02.02.2017 18:01

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

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


                                                                                                            1. Serginio1
                                                                                                              02.02.2017 18:16
                                                                                                              -1

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


                                                                                                              1. lair
                                                                                                                02.02.2017 18:18

                                                                                                                Угу JSON это та же строка.

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


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

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


                                                                                                                1. Serginio1
                                                                                                                  02.02.2017 18:23

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

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


                                                                                                                  1. lair
                                                                                                                    02.02.2017 18:25

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

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


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

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


                                                                                                                    1. Serginio1
                                                                                                                      02.02.2017 18:29
                                                                                                                      -1

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


                                                                                                                      1. lair
                                                                                                                        02.02.2017 18:30

                                                                                                                        В CEF есть только Double и Int

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


                                                                                                                        1. Serginio1
                                                                                                                          02.02.2017 19:42

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


                                                                                                                          1. lair
                                                                                                                            02.02.2017 21:39

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


                                                                                                                        1. Serginio1
                                                                                                                          02.02.2017 19:48

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


                                                                                                                          1. lair
                                                                                                                            02.02.2017 21:40

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


                                                                                                                            1. Serginio1
                                                                                                                              02.02.2017 22:19

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


                                                                                                                              1. lair
                                                                                                                                02.02.2017 22:35

                                                                                                                                Все делается в прокси.

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


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

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


                                                                                                                                1. Serginio1
                                                                                                                                  02.02.2017 22:37

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


                                                                                                                                  1. lair
                                                                                                                                    02.02.2017 22:41

                                                                                                                                    Вогт я написал прокси один раз. Зачем мне его поддерживать

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


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

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


                                                                                                                                    1. Serginio1
                                                                                                                                      02.02.2017 22:51

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

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

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

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


                                                                                                                                      1. lair
                                                                                                                                        02.02.2017 22:55

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

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


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

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


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

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


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


                                                                                                                                        1. Serginio1
                                                                                                                                          02.02.2017 23:08

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

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

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


                                                                                                                                          1. lair
                                                                                                                                            02.02.2017 23:11

                                                                                                                                            Там кода прокси максимум строк 100.

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


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

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


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


                                                                                                                                            1. Serginio1
                                                                                                                                              02.02.2017 23:21

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

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

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


                                                                                                                                              1. lair
                                                                                                                                                02.02.2017 23:29
                                                                                                                                                +1

                                                                                                                                                Как передать делегат и объект написано. Ты не читаешь.

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


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

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


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

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


                                                                                                                                                1. Serginio1
                                                                                                                                                  02.02.2017 23:34

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

                                                                                                                                                  А, днем чего делал. Заметь мы скоро рекорд побъем по количеству сообщений.
                                                                                                                                                  Дай мне написать события.


                                                                                                                                                  1. lair
                                                                                                                                                    02.02.2017 23:38

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

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


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

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


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

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


                                                                                                                                                    1. Serginio1
                                                                                                                                                      02.02.2017 23:50

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

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


                                                                                                                                                      1. lair
                                                                                                                                                        02.02.2017 23:54

                                                                                                                                                        Делегат это чисто C# понятие.

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


                                                                                                                                                        1. Serginio1
                                                                                                                                                          03.02.2017 00:05

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

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

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


                                                                                                                                                          1. lair
                                                                                                                                                            03.02.2017 00:07

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

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


                                                                                                                                                            1. Serginio1
                                                                                                                                                              03.02.2017 00:12

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


                                                                                                                                                              1. lair
                                                                                                                                                                03.02.2017 00:13

                                                                                                                                                                А при чем тут деревья выражений?

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


                                                                                                                                                                1. Serginio1
                                                                                                                                                                  03.02.2017 00:20

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

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

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


                                                                                                                                                                  Класс Expression

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

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

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


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


                                                                                                                                                                  1. lair
                                                                                                                                                                    03.02.2017 00:29

                                                                                                                                                                    Лямбда-выражения — это синтаксический сахар, который позволяет получить на выходе как функцию, так и дерево выражений. Меня интересовала вторая ипостась (потому что про первую мы уже выяснили, что ее нет). Когда я пишу типичный код 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 ииии понеслась.


                                                                                                                                                                    1. Serginio1
                                                                                                                                                                      03.02.2017 07:32

                                                                                                                                                                      1. lair
                                                                                                                                                                        03.02.2017 11:54

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


                                                                                                                                                                        Более того, вот возьмем мой пример, первый вызов (я убрал 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 (считал на глаз). Одна строчка кода.


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


                                                                                                                                                                        1. Serginio1
                                                                                                                                                                          03.02.2017 12:33

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

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


                                                                                                                                                                          1. lair
                                                                                                                                                                            03.02.2017 12:39

                                                                                                                                                                            Там под Net надо свой Linq делать с автоосвобождением ссылок.

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


                                                                                                                                                                            1. Serginio1
                                                                                                                                                                              03.02.2017 14:02

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


                                                                                                                                                                              1. lair
                                                                                                                                                                                03.02.2017 14:04

                                                                                                                                                                                Еще раз никто же тебе не запрещает писать на C# и использовать нормальный Linq.

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


                                                                                                                                                                                1. Serginio1
                                                                                                                                                                                  03.02.2017 14:06

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


                                                                                                                                                                                  1. lair
                                                                                                                                                                                    03.02.2017 14:08
                                                                                                                                                                                    -1

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


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


                                                                                                                                                                                    1. Serginio1
                                                                                                                                                                                      03.02.2017 14:24
                                                                                                                                                                                      -1

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


                                                                                                                                                                    1. Serginio1
                                                                                                                                                                      03.02.2017 07:44

                                                                                                                                                                      Ну а вообще так как мы можем получить итератор то можем использовать для этих целей 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к в секунду.
                                                                                                                                                                      Здесь лучше использовать гибридный подход


                                                                                                                                                                      1. lair
                                                                                                                                                                        03.02.2017 11:56

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

                                                                                                                                                                        Не-а.


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


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


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


                                                                                                                                                                        1. Serginio1
                                                                                                                                                                          03.02.2017 12:35

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


                                                                                                                                                                          1. lair
                                                                                                                                                                            03.02.2017 12:40

                                                                                                                                                                            Я вообще то не предлагаю все делать на стороне JS.

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


                                                                                                                                                                            1. Serginio1
                                                                                                                                                                              03.02.2017 14:00

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


                                                                                                                                                                              1. lair
                                                                                                                                                                                03.02.2017 14:03

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


                                                                                                                                                                                1. Serginio1
                                                                                                                                                                                  03.02.2017 14:05

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


                                                                                                                                                                                  1. lair
                                                                                                                                                                                    03.02.2017 14:06

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


                                                                                                                                                                                    1. Serginio1
                                                                                                                                                                                      03.02.2017 14:22
                                                                                                                                                                                      -1

                                                                                                                                                                                      Молодец!!! Повеселил. Ты хоть название то статьи вспомни.


                                                                                                                    1. Serginio1
                                                                                                                      02.02.2017 21:34
                                                                                                                      -1

                                                                                                                      Вот когда кажется
                                                                                                                      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


                                                                                                                      1. lair
                                                                                                                        02.02.2017 21:41

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


                                                                                                                        1. Serginio1
                                                                                                                          02.02.2017 22:23

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


                                                                                                                          1. lair
                                                                                                                            02.02.2017 22:40

                                                                                                                            Но реально в CEF два вида int и Double.

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


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


                                                                                                            1. Serginio1
                                                                                                              02.02.2017 19:49

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


                                                                                                              1. lair
                                                                                                                02.02.2017 21:42

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

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


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

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


                                                                                                                1. Serginio1
                                                                                                                  02.02.2017 22:29

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

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


                                                                                                                  1. lair
                                                                                                                    02.02.2017 22:43

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

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


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

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


                                                                                                                    1. Serginio1
                                                                                                                      02.02.2017 22:55

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

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

                                                                                                                      Там и тот и другой вариант можно использовать


                                                                                                                      1. lair
                                                                                                                        02.02.2017 22:59

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

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


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

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


                                                                                                                        1. Serginio1
                                                                                                                          02.02.2017 23:11

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

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

                                                                                                                          и посмотрим.

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


                                                                                                                          1. lair
                                                                                                                            02.02.2017 23:14

                                                                                                                            На Proxy кстати теряется процентов 30. Но они удобны.

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


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

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


                                                                                                                            1. Serginio1
                                                                                                                              02.02.2017 23:25

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

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


                                                                                                                              1. lair
                                                                                                                                02.02.2017 23:34

                                                                                                                                А насчет соревнования так это количество вызовов в секунду.

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


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


                                                                                                                                1. Serginio1
                                                                                                                                  02.02.2017 23:44

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

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

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


                                                                                                                                  1. lair
                                                                                                                                    02.02.2017 23:48

                                                                                                                                    Ну и сравни с моими 60к.

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


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

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


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

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


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

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


                                                                                                                                    1. Serginio1
                                                                                                                                      03.02.2017 00:00

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

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


                                                                                                                                      1. lair
                                                                                                                                        03.02.2017 00:05

                                                                                                                                        В чем оно не оптимально?

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


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

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


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

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


                                                                      1. Serginio1
                                                                        02.02.2017 16:22
                                                                        -1

                                                                        Как это нельзя. В первом же примере мы работаем исключительно с объектами.
                                                                        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);
                                                                        


                                                                        1. lair
                                                                          02.02.2017 16:25

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


                                                                          1. Serginio1
                                                                            02.02.2017 16:40

                                                                            Ту не смотрел код 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;
                                                                            	}
                                                                            


                                                                            1. Serginio1
                                                                              02.02.2017 16:41

                                                                              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;
                                                                              
                                                                                      }
                                                                              


                                                                            1. lair
                                                                              02.02.2017 16:44

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


                                                                              1. Serginio1
                                                                                02.02.2017 16:50

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


                                                                                1. lair
                                                                                  02.02.2017 16:52

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


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


                                                                                  1. Serginio1
                                                                                    02.02.2017 16:59

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


                                                                                    1. lair
                                                                                      02.02.2017 17:02
                                                                                      +1

                                                                                      Но скорости достаточно

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


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


                                                                                      1. Serginio1
                                                                                        02.02.2017 17:06
                                                                                        -1

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


                                                                                        1. lair
                                                                                          02.02.2017 17:10

                                                                                          То ты говорил, что out process это круто.

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


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

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


                                                                                          1. Serginio1
                                                                                            02.02.2017 17:16
                                                                                            -1

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


                                                                                            1. lair
                                                                                              02.02.2017 17:17

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

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


                                                                                              1. Serginio1
                                                                                                02.02.2017 17:26
                                                                                                -1

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


                                                                                                1. lair
                                                                                                  02.02.2017 17:27

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


                                                                                                  1. Serginio1
                                                                                                    02.02.2017 17:34
                                                                                                    -1

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


                                                                                                    1. lair
                                                                                                      02.02.2017 17:35

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

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


                                                                                                      1. Serginio1
                                                                                                        02.02.2017 17:54
                                                                                                        -1

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


                                                                                                        1. lair
                                                                                                          02.02.2017 17:56

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


                                                                                                          1. Serginio1
                                                                                                            02.02.2017 18:06

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


                                                                                                            1. lair
                                                                                                              02.02.2017 18:14

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


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


                                                                                                              1. Serginio1
                                                                                                                02.02.2017 18:20
                                                                                                                -1

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


                                                                                                                1. lair
                                                                                                                  02.02.2017 18:22

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


                                                                                                              1. Serginio1
                                                                                                                02.02.2017 20:10
                                                                                                                -1

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

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

                                                                                                                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);
                                                                                                                }
                                                                                                                


                                                                                                                Или предлагай свой вариант.


                                                                                                                1. lair
                                                                                                                  02.02.2017 21:43

                                                                                                                  Мы то говорим о браузерах.

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


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

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


                                                                                                                  1. Serginio1
                                                                                                                    02.02.2017 22:34

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

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

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


                                                                                                                    1. lair
                                                                                                                      02.02.2017 22:47

                                                                                                                      Это SignalR.

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


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

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


                                                                                                                      1. Serginio1
                                                                                                                        02.02.2017 22:59

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

                                                                                                                        А keep-alive на что. Так мне самому стало интересно. Меряем на ws и HTTP.


                                                                                                                        1. lair
                                                                                                                          02.02.2017 23:01

                                                                                                                          SignalR это протокол выбирающий оптимальный протокол обмена.

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


                                                                                                                          А keep-alive на что.

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


                                                                                                                          1. Serginio1
                                                                                                                            02.02.2017 23:17

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

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

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


                                                                                                                            1. lair
                                                                                                                              02.02.2017 23:24

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

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


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

                                                                                                                              По критерию?


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

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


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


                                                                                                                              1. Serginio1
                                                                                                                                02.02.2017 23:30

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

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

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


                                                                                                                                1. lair
                                                                                                                                  02.02.2017 23:41

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

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


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

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


                                                                                                                                  1. Serginio1
                                                                                                                                    02.02.2017 23:54

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


                                                                                                                                    1. lair
                                                                                                                                      02.02.2017 23:57

                                                                                                                                      Зачем писать 2 приложения, если можно все сделать в одном?

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


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


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

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


                                                                                                                                      1. Serginio1
                                                                                                                                        03.02.2017 00:09

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

                                                                                                                                        Дааа. Не понять мне Вас. И не мне одному Angular 2 и .Net Core


                                                                                                                                        1. lair
                                                                                                                                          03.02.2017 00:12

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

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


                                                                                                                                          1. Serginio1
                                                                                                                                            03.02.2017 00:13

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


                                                                      1. Serginio1
                                                                        02.02.2017 16:23
                                                                        -1

                                                                        Мало того еще есть и пример

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



                                                                    1. Serginio1
                                                                      02.02.2017 16:20

                                                                      Спасибо!


                                                                  1. Serginio1
                                                                    02.02.2017 16:18

                                                                    Так и будет

                                                                    let value=dict.get_Item("abc");
                                                                    


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

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


                                                                    1. lair
                                                                      02.02.2017 16:22

                                                                      Так и будет

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


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


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

                                                                      ?


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

                                                                      … и что?



                                                                      1. Serginio1
                                                                        02.02.2017 16:34

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

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

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


                                                                        1. lair
                                                                          02.02.2017 16:46

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

                                                                          Во-от.


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

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


                                                                          1. Serginio1
                                                                            02.02.2017 16:52

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


                                                                            1. lair
                                                                              02.02.2017 16:54

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


                                                                              var v = {a: "abc"}
                                                                              netObj.SetValue(v);
                                                                              netObj.Print(); //abc
                                                                              v.a = "def";
                                                                              netObj.Print(); //что будет напечатано?


                                                                              1. Serginio1
                                                                                02.02.2017 17:02
                                                                                -1

                                                                                Еще раз. Я говрил, что на данный момент нет поддержи JS объектов, но она будет только на время вызова.

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


                                                                                1. lair
                                                                                  02.02.2017 17:03

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


                                                                                  1. Serginio1
                                                                                    02.02.2017 17:08

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


                                                                                    1. mayorovp
                                                                                      02.02.2017 17:09

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


                                                                                      1. Serginio1
                                                                                        02.02.2017 17:13

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


                                                                                        1. lair
                                                                                          02.02.2017 17:14
                                                                                          +1

                                                                                          И будут реализованы только на время вызова.

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


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

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


                                                                                          1. Serginio1
                                                                                            02.02.2017 17:25

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

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


                                                                                            1. lair
                                                                                              02.02.2017 17:26

                                                                                              netObj.Print(); //abc // Здесь уже нет никакго v

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


                                                                                              1. Serginio1
                                                                                                02.02.2017 17:33

                                                                                                Если будет внутри методпа

                                                                                                voit TestJS(dynamic v)
                                                                                                {
                                                                                                netObj.SetValue(v);
                                                                                                netObj.Print(); //abc
                                                                                                v.a = "def";
                                                                                                netObj.Print(); 
                                                                                                
                                                                                                }
                                                                                                


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


                                                                                                1. lair
                                                                                                  02.02.2017 17:34

                                                                                                  Если будет внутри методпа

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


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

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


                                                                                                  1. Serginio1
                                                                                                    02.02.2017 17:44

                                                                                                    в 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 есть


                                                                                                    1. lair
                                                                                                      02.02.2017 17:45

                                                                                                      в JS нет понятия

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


                                                                                                      1. Serginio1
                                                                                                        02.02.2017 18:04

                                                                                                        Еще раз я тебе уже расписывал.
                                                                                                        На стороне 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
                                                                                                        члены которого будут уничтожаться при выходе из метода.


                                                                                                        1. lair
                                                                                                          02.02.2017 18:08

                                                                                                          На стороне CEF я могу сохранить ссылку

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


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

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


                                                                                                          1. Serginio1
                                                                                                            02.02.2017 18:18

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

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


                                                                                                            1. lair
                                                                                                              02.02.2017 18:19

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

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


                                                                                                              1. Serginio1
                                                                                                                02.02.2017 18:25
                                                                                                                -1

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


                                                                                                                1. lair
                                                                                                                  02.02.2017 18:26

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


                                                                                    1. lair
                                                                                      02.02.2017 17:12
                                                                                      +1

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


                                                                                      1. Serginio1
                                                                                        02.02.2017 17:18

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


                                                                                        1. lair
                                                                                          02.02.2017 17:20

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


                                                                                          1. Serginio1
                                                                                            02.02.2017 17:27
                                                                                            -1

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


                                                                                            1. lair
                                                                                              02.02.2017 17:29

                                                                                              remoting твой любимы out process.

                                                                                              Кстати, нет.


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

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


                                                                                              1. Serginio1
                                                                                                02.02.2017 17:37

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

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


                                                                                                1. lair
                                                                                                  02.02.2017 17:39

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

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


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

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


                                                                                                  1. Serginio1
                                                                                                    02.02.2017 17:57

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


                                                                                                    1. lair
                                                                                                      02.02.2017 18:00

                                                                                                      Тогда и не говори, что COM никому не нужен.

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


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

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


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


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

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


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

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


                                                                                                      1. Serginio1
                                                                                                        02.02.2017 18:15

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

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


                                                                                                        1. lair
                                                                                                          02.02.2017 18:17
                                                                                                          +1

                                                                                                          Вот а как раз и предлагаю замену COM на линукс.

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


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

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


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

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


                                                                                                          1. Serginio1
                                                                                                            02.02.2017 18:22

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

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


                                                                                                            1. lair
                                                                                                              02.02.2017 18:23

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

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


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

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


                                                                                                              1. Serginio1
                                                                                                                02.02.2017 18:27
                                                                                                                -1

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


                                                                                                                1. lair
                                                                                                                  02.02.2017 18:29

                                                                                                                  Это ты все ратуешь за вэб и HTTP сервисы/

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


                                  1. denismaster
                                    02.02.2017 13:46

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


                                    ws = WebSockets, если что. Можно и другие способы организовать взаимодействие, но я имел в виду именно связку что приложение выполняется локально. Desktop еще не настолько умер.


                                    1. Serginio1
                                      02.02.2017 13:53

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


                                      1. lair
                                        02.02.2017 14:16

                                        Я про SignalR говорил. Ws это просто разновидность этого протокола.

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


                                        1. Serginio1
                                          02.02.2017 14:25

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


                                          1. lair
                                            02.02.2017 14:28

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


                                            1. Serginio1
                                              02.02.2017 14:30

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


                                              1. lair
                                                02.02.2017 14:32

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


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


                                                1. Serginio1
                                                  02.02.2017 14:34
                                                  -1

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


                                    1. lair
                                      02.02.2017 14:16

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


                          1. Serginio1
                            02.02.2017 13:09

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

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


                            1. lair
                              02.02.2017 13:13
                              +1

                              Для решения задач можно пойти 2 путями.

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


                              1. Serginio1
                                02.02.2017 13:21

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


                                1. lair
                                  02.02.2017 13:23

                                  А зачем мне это делать, если мне проще вызвать напрямую.

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


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

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


                                  1. Serginio1
                                    02.02.2017 13:36
                                    -1

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

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


                                    1. lair
                                      02.02.2017 14:17

                                      А из чистого браузера никак не получится.

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


                                      1. Serginio1
                                        02.02.2017 14:27

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


                                        1. lair
                                          02.02.2017 14:29

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


                                          1. Serginio1
                                            02.02.2017 14:32

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


                                            1. lair
                                              02.02.2017 14:37

                                              Угу теперь остается только делать адаптер, http сервис итд.

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


                                              1. Serginio1
                                                02.02.2017 14:43

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

                                                Я ни кто, и зовут меня ни как. Но тот же Electron будут с удовольствием использовать ибо…


  1. vtulin
    01.02.2017 23:43
    +3

    «Нет времени» — не пиши, напишешь, когда будет время собраться и написать статью.


    1. Serginio1
      02.02.2017 10:16
      -1

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

      Но сама разработка велась еще раньше. При этом от этого я никаких дивидентов не получаю. В основном тычки «зачем это нужно», но есть конечно и благодарности, но их немного. При этом реально легко можно расширить возможности для 1С. Но и 1С это не нужно. Мои разработки Но я не опускаю руки. Днем программирую на 1С, а вечером еще на C#,C++ и TypeScript.
      При этом катастрофически не высыпаюсь. Но в разработке много интересного и я хочу поделиться этим с коллегами, надеясь, что коллеги простят мне мой руслиш и войдут в моё нелегкое положение. При этом я прекрасно понимаю, что получу кучу минусов. Но надеюсь, что за мои труды мне полагается небольшое снисхождение.


      1. denismaster
        02.02.2017 11:46

        Статья очень интересная, не падай духом))Много полезного материала. Но думаю людям не совсем понятно, как и для чего этого нужно. Я думаю, если бы в картинках показать как связать тот же Electron+.NET, то было бы намного наглядней)


        1. Serginio1
          02.02.2017 12:39

          Огромное спасибо за поддержку. Проблема в том, что я один. У меня огромное время уходит на изучение C++, TypeScrpt и еще кучи вещей что бы связать JS-native-Net.При этом я работаю программистом 1С. Все это в свободное от работы время. Плюс я плохой художник. Выложил программы, но на данный момент их скачали всего 4 человека.


      1. vtulin
        02.02.2017 16:37

        Тема интересная, не опускайте руки — пишите и держите в уме, что кому-то (нам) это читать:)


        1. Serginio1
          02.02.2017 16:43

          Спасибо! Я стараюсь. Сейчас переписываю эвенты на инглиш


  1. Serginio1
    01.02.2017 23:57
    -2

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


  1. medvedevia
    04.02.2017 13:38

    Вот тут в соседней теме по Xamarin люди делятся ссылками Avalonia.A multi-platform .NET UI framework. It can run on Windows, Linux, Mac OS X, iOS and Android.
    Вообще, судя по комментами, то больше распространена практика, когда бизнес логику пишут кроссплатформенно, а гуи под каждую платформу по гайдлайнам.


    1. Serginio1
      04.02.2017 13:59

      Про авалонию я знаю. Она еще в альфе. Ну так и я предлагаю ГУИ писать на Angular 2, на кроссплатформеном .Net Core. Скоро выйдет NetStandard 2 и .Net Core 1.2 и возможностей будет значительно больше.


      1. medvedevia
        04.02.2017 21:57

        Она еще в альфе.

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

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

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


        1. Serginio1
          04.02.2017 23:49
          -1

          Ну так 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. Serginio1
      04.02.2017 14:16

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

      Я сторонник тонкого клиента. При этом код который сделан под WPF и UWP можно легко перенести на Angular 2 стремительно развивается. Но кто такой я?