考虑使用Apache Ignite.NET库的类
public interface ICluster
{
void Join();
void Leave();
}
public class ApacheIgniteClusterImpl : ICluster
{
private IIgnite Ignite { get; set; }
private int MulticastPort { get; }
private int ThinClientPort { get; }
public ApacheIgniteClusterImpl(int multicastPort = 47401, int thinClientPort = 10800)
{
MulticastPort = multicastPort;
ThinClientPort = thinClientPort;
}
public void Join()
{
if (Ignite != null)
{
return;
}
var configuration = new IgniteConfiguration
{
ClientConnectorConfiguration = new ClientConnectorConfiguration
{
Port = ThinClientPort,
},
DiscoverySpi = new TcpDiscoverySpi
{
IpFinder = new TcpDiscoveryMulticastIpFinder()
{
MulticastPort = MulticastPort,
}
},
JvmOptions = new List<string>()
{
"-DIGNITE_NO_SHUTDOWN_HOOK=true",
},
};
// Start
Ignite = Ignition.Start(configuration);
}
public void Leave()
{
Ignition.Stop(null, true);
Ignite = null;
}
}
通常,在.NET Standard中,允许我们挂入AppDomain.CurrentDomain.ProcessExit
事件,在该事件中我们可以进行清理工作。但是,一旦由Apache Ignite.NET创建了JVM,当我使用AppDomain.CurrentDomain.ProcessExit
杀死MacOS上的控制台应用程序时,就永远不会触发{1>}。
我在调试时做了一些研究,发现它会在调用kill <pid>
之后的某个地方发生。
任何想法都在那里发生了,如果有机会我们可以加入private static Jvm CreateJvm(IgniteConfiguration cfg, ILogger log)
吗?
UPD :AppDomain.CurrentDomain.ProcessExit
和AppDomain.CurrentDomain.DomainUnload
都不起作用。
答案 0 :(得分:2)
ProcessExit
is not guaranteed to be called。
我相信Ignite.NET与此无关。我已经检查了这一点(没有引用或启动Ignite),并且如果您强行终止该过程,则不会调用该处理程序。
答案 1 :(得分:1)
根据Oracle's Java Documentation:
嵌入JVM的应用程序经常需要捕获SIGINT或SIGTERM之类的信号,这可能会导致干扰JVM信号处理程序。 -Xrs选项可用于解决此问题。使用-Xrs时,JVM不会更改SIGINT,SIGTERM,SIGHUP和SIGQUIT的信号掩码,并且不会安装这些信号的信号处理程序。
因此,在稍微修改了初始类之后,我就能够处理AppDomain.CurrentDomain.ProcessExit
和Console.CancelKeyPress
// ...
JvmOptions = new List<string>()
{
"-Xrs", // <--------------------
"-DIGNITE_NO_SHUTDOWN_HOOK=true",
},
// ...