在Mono中使用UnixSignal引发System.ArgumentException

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

根据Mono文档 ,build议在单独的线程中运行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

未处理的exception:System.ArgumentException:无法处理信号参数名称:在Mono.Unix.UnixSignal..ctor(Signum signum)上的符号<0x40433de0 + 0x00097> in:0(在包装器远程调用与检查)Mono.Unix .UnixSignal:.ctor(Mono.Unix.Native.Signum)at MangoFareScrapingGenericClient.Scraping.ListenToSignal()<0x404339e0 + 0x00117> in:0在System.Threading.ThreadHelper.ThreadStart_Context(System.Object状态)<0x7f20f10b1010 + 0x00099>中:System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext,System.Threading.ContextCallback callback,System.Object state,Boolean preserveSyncCtx)中的位置为0:0x7f20f10af850 + 0x0016e System.Threading.ExecutionContext executionContext,System.Threading.ContextCallbackcallback,System.Object状态,布尔preserveSyncCtx)<0x7f20f10af820 + 0x00020>中:0在System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext,System .Threading.ThreadHelper.ThreadStart()<0x7f20f10b11d0 + 0x0002e> in:0中的.Threading.ContextCallbackcallback,System.Object状态)<0x7f20f10af770 + 0x00059>

如果我看Github的特定代码,它看起来像signal_info是一个IntPtr.Zero引发exception。

 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中(我记得pull-request,因为我需要在部署中提供支持)

所以我假设 SIGQUITSIGHUP无法安装。

但是 ,既然你没有说哪个信号返回了一个IntPtr.Zero并抛出exception,我会试着自己安装每个信号来find你的Ubuntu Docker环境中不支持的信号。

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

另外,您可以尝试/抓住您的UnixSignal.WaitAny并正常降级您的信号处理,并写出有关违规信号的日志消息。