一尘不染

如何强行阻止Node.js进程终止?

node.js

TL; DR

强制保持Node.js进程运行的最佳方法是什么,即使其事件循环不为空,从而防止进程终止?我能想到的最好的解决方案是:

const SOME_HUGE_INTERVAL = 1 << 30;
setInterval(() => {}, SOME_HUGE_INTERVAL);

如果您将间隔时间保持足够长,它将使间隔运行,而不会引起过多干扰。

有更好的方法吗?

问题的长版

我有一个使用Edge.js来注册回调函数的Node.js脚本,以便可以从.NET中的DLL内部对其进行调用。每秒将调用此功能1次,发送一个应打印到控制台的简单序列号。

Edge.js部分很好,一切正常。我唯一的问题是我的Node.js进程执行其脚本,然后用完所有事件以进行处理。事件循环为空,它只是终止,而忽略了它应该一直运行以便能够从DLL接收回调的事实。

我的Node.js脚本:

var
    edge = require('edge');

var foo = edge.func({
    assemblyFile: 'cs.dll',
    typeName: 'cs.MyClass',
    methodName: 'Foo'
});

// The callback function that will be called from C# code:
function callback(sequence) {
    console.info('Sequence:', sequence);
}

// Register for a callback:
foo({ callback: callback }, true);

// My hack to keep the process alive:
setInterval(function() {}, 60000);

我的C#代码(DLL):

public class MyClass
{
    Func<object, Task<object>> Callback;

    void Bar()
    {
        int sequence = 1;

        while (true)
        {
            Callback(sequence++);
            Thread.Sleep(1000);
        }
    }

    public async Task<object> Foo(dynamic input)
    {
        // Receives the callback function that will be used:
        Callback = (Func<object, Task<object>>)input.callback;

        // Starts a new thread that will call back periodically:
        (new Thread(Bar)).Start();

        return new object { };
    }
}

我唯一能想到的解决方案是注册一个间隔很长的计时器来调用一个空函数,以使调度程序保持繁忙并避免使事件循环为空,从而使进程永远运行。

有什么办法比我做得更好吗?即, 无需 使用这种“ hack”就可以保持进程运行?


阅读 285

收藏
2020-07-07

共1个答案

一尘不染

尽管看起来这个问题没有正确的答案,但到目前为止,我们有3种可能的破解方法,老实说,我认为我的方法是侵入性较小的方法:

setInterval(() => {}, 1 << 30);

这将设置一个间隔,大约每12天触发一次。

最初,我的破解Number.POSITIVE_INFINITY是在周期内过去的,因此计时器实际上永远不会触发,但是这种行为最近已更改,现在API不接受大于2147483647(即2 ** 31 - 1)的值。在此处此处查看文档。

作为参考,下面是到目前为止给出的其他两个答案:

乔的:

require('net').createServer().listen();

将创建一个“伪侦听器”,正如他所说的那样。一个较小的缺点是,我们仅为此分配了一个端口。

雅各的:

process.stdin.resume();

或等效的:

process.stdin.on("data", () => {});

stdin成“旧”模式,弃用的功能,仍然存在于Node.js的用于与Node.js的v0.10(之前编写的脚本兼容性参考)。

2020-07-07