Apache Ignite.NET and AppDomain.CurrentDomain.ProcessExit



考虑类,利用 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 创建了 JVM,当我使用kill <pid>杀死 MacOS 上的控制台应用程序时,Ignite.NETAppDomain.CurrentDomain.ProcessExit永远不会被触发。

我在调试时做了一些研究,发现它会在调用private static Jvm CreateJvm(IgniteConfiguration cfg, ILogger log)后的某个地方发生。

知道那里发生了什么,如果有机会我们可以钩AppDomain.CurrentDomain.ProcessExit

UPDAppDomain.CurrentDomain.DomainUnloadSystem.Runtime.Loader.AssemblyLoadContext.Unloading都行不通。

不能保证调用ProcessExit

我相信 Ignite.NET 与此无关。我已经检查过这一点(不引用或启动 Ignite(,如果您强制终止进程,则不会调用处理程序。

根据Oracle的Java文档:

嵌入 JVM

的应用程序经常需要捕获信号,例如 SIGINT 或 SIGTERM,这可能会导致对 JVM 信号处理程序的干扰。-Xrs 选项可用于解决此问题。使用 -Xrs 时,JVM 不会更改 SIGINT、SIGTERM、SIGHUP 和 SIGQUIT 的信号掩码,并且不会安装这些信号的信号处理程序。

因此,在稍微修改初始类后,我能够处理AppDomain.CurrentDomain.ProcessExitConsole.CancelKeyPress

// ...
JvmOptions = new List<string>()
{
"-Xrs", // <--------------------
"-DIGNITE_NO_SHUTDOWN_HOOK=true",
},
// ...

最新更新