我有一个 C# 控制台程序“A”来监视另一个应用程序“B”的 4 个实例。
控制台程序为每个“B”实例创建一个线程,每个线程使用Process.Start()
. 然后线程使用等待 3 秒Process.WaitForExit(3000);
在那之后,它会检查应用程序“B”的实例是否正在运行。如果没问题,再等。否则,如果它不起作用或已经完成,它会重新启动它。当用户关闭控制台程序时,所有应用程序都将结束。
但是,当使用控制台的关闭按钮关闭应用程序“A”时,WaitForExit() 在所有线程中恢复,并导致应用程序“B”重新启动。
我想检测是否WaitForExit()
由于受监控的应用程序“B”失败或主应用程序“A”正在退出而恢复。在这种情况下,应用程序“B”不会重新启动,问题将得到解决。
我尝试使用以下方法捕获结束事件:
[DllImport("Kernel32")]
public static extern bool SetConsoleCtrlHandler(HandlerRoutine Handler, bool Add);
问题是在调用处理程序例程之前恢复了 WaitForExit()。
更多信息:
Main() 方法启动线程:
for(int i = 0; i < 4; i++)
{
Thread t = new Thread(() => MonitorizeApp(arguments));
t.IsBackground = true;
t.Start();
}
我还尝试将线程从后台更改为前台,以便主应用程序不会退出,但结果是一样的。
每个线程启动并监视第二个应用程序的一个实例:
MonitorizeApp(string arguments)
{
LaunchProcess(arguments);
while(!_closing)
{
appProcess.WaitForExit(3000);
if (!_closing)
{
if ((appProcess != null) && (!appProcess.HasExited))
DoSomeMonitoring();
else
{
Console.WriteLine("WARNING: The application finished");
Thread.Sleep(500);
if (!_closing)
{
Console.WriteLine("Re-launch");
LaunchProcess(arguments);
inicial = true;
}
}
}
}
Console.WriteLine("\nClosing...\n");
if(appProcess != null)
{
if(!appProcess.HasExited)
appProcess.Kill();
appProcess.Dispose();
}
}
_closure 是在控制台关闭时从主线程设置的变量。我使用 SetConsoleCtrlHandler 做到了这一点:
[DllImport("Kernel32")]
public static extern bool SetConsoleCtrlHandler(HandlerRoutine Handler, bool Add);
public delegate bool HandlerRoutine(CtrlTypes CtrlType);
private static bool ConsoleCtrlCheck(CtrlTypes ctrlType)
{
MonitoredApp.closing = true;
Thread.Sleep(1000);
closing = true;
Environment.Exit(-1);
return true;
}