使用Edge with Node时,承诺未完成

时间:2016-05-26 21:58:10

标签: c# node.js typescript async-await edgejs

我正在研究如何使用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结构都不响应已经解析(结果)执行。

我发现如果我是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出现问题。为了公平起见,我原本预计承诺将是强劲的。使用Typescript,Node,Edge,Promises,Q时可能会出现问题。

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

标记

1 个答案:

答案 0 :(得分:0)

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

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

console.log 是一个很好的解决方法,但我想要一些安静的东西。我注意到控制台内部有_stdout。如果您执行 console._stdout.write(&#39;&#39;); ,您将获得无声解锁。在Typescript中你必须做(控制台为任何)._ stdout.write(&#39;&#39;);

我在进入边缘代理回调时执行此操作。 e.g。

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

显然,您可以按照评论中的说明记录某些内容。