0

我正在研究如何最好地使用 Edgejs for Node 来使用我的 C# dll。

Node 中的一个代理函数如下所示(Typescript 中的类方法):

readSettings(args: ReadSettingsParams) : Promise<response> {
    let $engine = this;
    var proxy = edge.func({
        assemblyFile: "C:\\Development\\IAStash\\GLReport\\GLReport\\bin\\x64\\Debug\\GLReportEngine.dll",
        typeName: "GLReportEngine.edgeGLReport",
        methodName: "readSettings"
    });
    return new Promise<response>(function (resolve, reject) {
        args.instance = $engine.instance;
        proxy(args, function(error, result) {
            if (error) {
                reject(error);
            } else {
                resolve(result);
            }
        });
    });
}

当我在 c# 中的复杂任务是同步的时,一切都按预期工作,但是当我将 c# 函数的核心移动到一个任务中时:

return await Task.Run<object>( () => { do some stuff });

当我使用上述模式时,resolve(result) 行被命中,结果在监视窗口中是正确的,但是任何组成的 .then 或 Q.all 结构都不会响应 resolve(result) 已执行。

我发现如果我 console.log("x"); 在代理回调返回之前,我的组合 .then 和 Q.all 结构按预期触发。即这个版本有效:

readSettings(args: ReadSettingsParams) : Promise<response> {
    let $engine = this;
    var proxy = edge.func({
        assemblyFile: "C:\\Development\\IAStash\\GLReport\\GLReport\\bin\\x64\\Debug\\GLReportEngine.dll",
        typeName: "GLReportEngine.edgeGLReport",
        methodName: "readSettings"
    });
    return new Promise<response>(function (resolve, reject) {
        args.instance = $engine.instance;
        proxy(args, function(error, result) {
            console.log("GLReportProxy.readSettings proxy returns, Err = " + (!!error));
            if (error) {
                reject(error);
            } else {
                resolve(result);
            }
        });
    });
}

在这种情况下,我的 c# 例程读取一个 xml 文件,对其进行反序列化并返回它:

    public Task<object> readSettings(object args)
    {
        if (args != null && typeof(System.Dynamic.ExpandoObject).IsAssignableFrom(args.GetType()))
        {
            var argdict = (IDictionary<string, object>)args;
            if (argdict.ContainsKey("report"))
            {
                reportsettingsfile = argdict["report"].ToString();
            }

            return Task.Run<object>(
                () => {
                    if (File.Exists(reportsettingsfile))
                    {
                        var xser = new XmlSerializer(typeof(ReportSettings.report));
                        string settingstext = File.ReadAllText(reportsettingsfile);
                        using (var tre = new StringReader(settingstext))
                        {
                            reportSettings = (ReportSettings.report)xser.Deserialize(tre);
                        }
                        return new { result = true, model = reportSettings };
                    }
                    else
                    {
                        return new { result = false, error = "File not found" };
                    }
                });
        } else
        {
            return Task.FromResult<object>(new { result = false, error = "Expected (input) object but can't read it." });
        }
    }

这相当简单。我认为我在使用 async/await 时遇到了问题,这会导致 Node.js 出现问题。不过说句公道话,我曾期望诺言是稳健的。我对 Typescript、Node、Edge、Promises、Q 的使用可能存在问题。

如果有人知道发生了什么,以及为什么登录到控制台可以解决问题。我会很感激任何帮助!

标记

4

1 回答 1

0

我发现当在同一个进程中有一个 http.listener 和 ac# 边缘代理回调时,这是一个问题。可能还有其他组合,但库之间的一些相互作用是根本原因。

由于根据 edgejs 未解决此问题,因此 console.log 方法是一个很好的解决方法,特别是如果您不介意在日志窗口中写入一些有用的消息。

console.log是一个很好的解决方法,但我想要一些安静的东西。我注意到控制台内部有 _stdout。如果执行console._stdout.write(''); 你会得到一个无声的解锁。在打字稿中你必须做的(任何控制台)._stdout.write(''); .

我在进入边缘代理回调时执行此操作。例如

readSettings(args: ReadSettingsParams) : Promise<response> {
    let $engine = this;
    var proxy = edge.func({
        assemblyFile: "C:\\Development\\IAStash\\GLReport\\GLReport\\bin\\x64\\Debug\\GLReportEngine.dll",
        typeName: "GLReportEngine.edgeGLReport",
        methodName: "readSettings"
    });
    return new Promise<response>(function (resolve, reject) {
        args.instance = $engine.instance;
        proxy(args, function(error, result) {
            (console as any)._stdout.write('');
            //console.log("GLReportProxy.readSettings proxy returns, Err = " + (!!error));
            if (error) {
                reject(error);
            } else {
                resolve(result);
            }
        });
    });
}

显然,您可以按照评论中的指示记录一些内容。

于 2016-05-27T14:15:08.640 回答