在Mono中使用UnixSignal会抛出System.ArgumentException

时间:2016-05-03 15:57:49

标签: c# .net ubuntu docker mono

我有一个控制台应用程序在Docker容器中的单声道上运行.Net 4.6.1并且运行正常。在进一步开发应用程序时,我正在考虑使用Nuget-package 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

  

未处理的异常:System.ArgumentException:无法处理信号   参数名称:Signo at Mono.Unix.UnixSignal..ctor(Signum signum)   &lt; 0x40433de0 + 0x00097&gt; in:0 at(包装器   remoting-invoke-with-check)Mono.Unix.UnixSignal:.ctor   (Mono.Unix.Native.Signum)在   MangoFareScrapingGenericClient.Scraping.ListenToSignal()&lt; 0x404339e0   + 0x00117&gt; in:0在System.Threading.ThreadHelper.ThreadStart_Context(System.Object   状态)&lt; 0x7f20f10b1010 + 0x00099&gt; in:0 at   System.Threading.ExecutionContext.RunInternal   (System.Threading.ExecutionContext executionContext,   System.Threading.ContextCallback回调,System.Object状态,   Boolean preserveSyncCtx)&lt; 0x7f20f10af850 + 0x0016e&gt; in:在System.Threading.ExecutionContext.Run中为0   (System.Threading.ExecutionContext executionContext,   System.Threading.ContextCallback回调,System.Object状态,   Boolean preserveSyncCtx)&lt; 0x7f20f10af820 + 0x00020&gt; in:在System.Threading.ExecutionContext.Run中为0   (System.Threading.ExecutionContext executionContext,   System.Threading.ContextCallback回调,System.Object状态)   &lt; 0x7f20f10af770 + 0x00059&gt; in:0 at   System.Threading.ThreadHelper.ThreadStart()&lt; 0x7f20f10b11d0 +   0x0002e&GT; in:0

如果我在Github上查找具体的code,看起来signal_infoIntPtr.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");
    }
}

1 个答案:

答案 0 :(得分:1)

在〜2013年,

SIGTERMSIGINT支持被添加到Docker中(我记得拉取请求,因为我需要部署中的支持)

所以我假设 SIGQUITSIGHUP未能安装。

,因为您没有说明哪个信号返回IntPtr.Zero并因此抛出异常,我会尝试自行安装每个信号找到Ubuntu Docker环境中不支持的那个。

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

另外,你可以尝试/抓住你的UnixSignal.WaitAny并优雅地降低你的信号处理能力并写下有关违规信号的日志信息。