在 Mono 中使用 UnixSignal 抛出 System.ArgumentException

Using UnixSignal in Mono throws System.ArgumentException

我在 Docker 容器中有一个控制台应用程序 运行 .Net 4.6.1 on mono,它运行良好。在进一步开发应用程序时,我正在研究使用 Nuget 包 Mono.Posix 响应 unix 信号。

根据Mono documentation建议运行UnixSignal在单独的线程中处理。

所以我正在尝试像下面的代码那样做:

public void Run()
{
    var signalHandler = new Thread(new ThreadStart(ListenToSignal));
    signalHandler.Start();
}

private void ListenToSignal()
{
    var signals = new List<UnixSignal>() {
        new UnixSignal (Mono.Unix.Native.Signum.SIGHUP),
        new UnixSignal (Mono.Unix.Native.Signum.SIGINT),
        new UnixSignal (Mono.Unix.Native.Signum.SIGQUIT),
        new UnixSignal (Mono.Unix.Native.Signum.SIGTERM)
    };

    int index = UnixSignal.WaitAny(signals.ToArray());
    var signal = signals[index].Signum;
    Console.WriteLine($"Terminate signal was called: {signal}");
}

启动应用程序时它会抛出 ArgrumentException:

Unhandled Exception: System.ArgumentException: Unable to handle signal Parameter name: signum at Mono.Unix.UnixSignal..ctor (Signum signum) <0x40433de0 + 0x00097> in :0 at (wrapper remoting-invoke-with-check) Mono.Unix.UnixSignal:.ctor (Mono.Unix.Native.Signum) at MangoFareScrapingGenericClient.Scraping.ListenToSignal () <0x404339e0 + 0x00117> in :0 at System.Threading.ThreadHelper.ThreadStart_Context (System.Object state) <0x7f20f10b1010 + 0x00099> in :0 at System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, Boolean preserveSyncCtx) <0x7f20f10af850 + 0x0016e> in :0 at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, Boolean preserveSyncCtx) <0x7f20f10af820 + 0x00020> in :0 at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state) <0x7f20f10af770 + 0x00059> in :0 at System.Threading.ThreadHelper.ThreadStart () <0x7f20f10b11d0 + 0x0002e> in :0

如果我在 Github 上查找特定的 code,它看起来 signal_info 是一个 IntPtr.Zero,它会抛出异常。

public UnixSignal (Signum signum)
{
    this.signum = NativeConvert.FromSignum (signum);
    this.signal_info = install (this.signum);
    if (this.signal_info == IntPtr.Zero) {
        throw new ArgumentException ("Unable to handle signal", "signum");
    }
}

SIGTERMSIGINT 支持已在 ~2013 年添加到 Docker(我记得拉取请求,因为我在部署中需要该支持)

所以我假设 SIGQUITSIGHUP 安装失败。

但是,因为你没有说哪个信号返回 IntPtr.Zero 从而抛出异常,我会尝试安装 each 自行发出信号以找到您的 Ubuntu Docker 环境中不支持的信号。

那时,您可以在直接 C 程序下测试该信号以确定它是否运行正常,因为它可能是 Mono 运行时 运行 下的问题 Docker.

此外,您可以 try/catch 您的 UnixSignal.WaitAny 并优雅地降低您的信号处理能力,并编写有关违规信号的日志消息。