使用EdgeJs调用Node函数时程序触发无限等待发生卡死是什么原因?
问题根因分析
这是典型的异步方法同步上下文死锁问题:
- 你在同步方法
chamar()中调用NodeFunc().Wait(),会阻塞当前线程,等待异步任务完成 - Edge.js执行完Node侧逻辑触发回调时,默认会尝试回到调用
await前的同步上下文执行后续代码,而这个上下文已经被Wait()阻塞占用,二者互相等待形成死锁 - 你看到的线程退出日志是Edge.js启动的Node.js工作线程完成任务后正常退出的提示,不代表异常,只是主线程因为死锁永远拿不到返回结果
解决方案
场景1:可调整调用链为全异步
把所有调用路径改成异步,避免用Wait()/.Result这类同步阻塞方法,修改后代码如下:
{ class Interpreter { public static async Task NodeFunc() { var func = Edge.Func(@" return function (data, callback) { callback(null, 'Node.js welcomes ' + data); } "); Console.WriteLine(await func(".NET")); } // 改为异步方法 public static async Task chamar() { await NodeFunc(); } } }
调用chamar()的位置也统一用await执行即可。
场景2:必须保留同步调用逻辑
如果上层调用逻辑无法改成异步,给await语句添加ConfigureAwait(false),不让异步回调尝试捕获原同步上下文,即可避免死锁:
{ class Interpreter { public static async Task NodeFunc() { var func = Edge.Func(@" return function (data, callback) { callback(null, 'Node.js welcomes ' + data); } "); // 添加ConfigureAwait(false) Console.WriteLine(await func(".NET").ConfigureAwait(false)); } public static void chamar() { NodeFunc().Wait(); } } }
内容的提问来源于stack exchange,提问作者Spyro
相关产品推荐
相关产品推荐

