【发布时间】:2023-03-26 19:56:01
【问题描述】:
我有一个 C# 控制台程序“A”来监视另一个应用程序“B”的 4 个实例。
控制台程序为每个“B”实例创建一个线程,每个线程使用Process.Start() 启动“B”。然后线程使用Process.WaitForExit(3000);等待3秒
在那之后,它会检查应用程序“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;
}
【问题讨论】:
-
WaitForExit将返回一个布尔值,指示进程是否已退出或超时已过。也许这就是你所追求的?
标签: c# multithreading console waitforexit