C# .NET 3.5프로그램이 자체 프로세스를 종료하는 올바른 방법은 무엇입니까? (Windows)
컴퓨터의 다른 응용 프로그램에서 호출하는 콘솔 응용 프로그램이 있습니다. 이 콘솔 앱은 지속적으로 실행되며 "상위"프로세스의 stdin에서 데이터를 수신합니다.
그러나 부모가 중지되거나 종료되면 콘솔 앱이 계속 시작됩니다. 정상적인 상황에서는 최소한의 리소스를 사용하여 stdin에서 입력을 기다리고 앉아 있습니다. 그러나 부모가 사라지 자마자이 콘솔 앱은 CPU를 급증시키고 거의 100 % 사용률로 실행중인 코어를 굶어 죽입니다. 이 작업은 수동으로 프로세스를 종료 할 때까지 계속됩니다.
정상적인 경우 (예외적이지 않은) "중지"조건에서 발생하기 때문에 호출 부모가 이상적으로 정리하는 것이 이상적입니다. 불행히도,이 부모 프로세스는 내 손에서입니다.
내 첫 번째 생각은 콘솔 앱에서 호출하는 상위 프로그램을 가져 와서 해당 PID를 모니터링하는 것이 었습니다. 부모 프로세스가 사라지면 콘솔 앱이 종료됩니다. 현재, 나는 이것을하고 있어요 :
Process process = Process.GetCurrentProcess();
m_ParentPID = 0;
using (ManagementObject mgmtObj = new ManagementObject("win32_process.handle='" + process.Id.ToString() + "'"))
{
mgmtObj.Get();
m_ParentPID = Convert.ToInt32(mgmtObj["ParentProcessId"]);
}
string parentProcessName = Process.GetProcessById(m_ParentPID).ProcessName;
Log("Parent Process: " + parentProcessName + Environment.NewLine);
// Create a timer for monitoring self.
Timer timer = new Timer(new TimerCallback(sender =>
{
if (m_ParentPID != 0)
{
Process parent = System.Diagnostics.Process.GetProcessById(m_ParentPID);
if (parent == null)
{
Log("Parent process stopped/killed. Terminating self.");
System.Environment.Exit(0);
}
}
}));
// Kick on the timer
timer.Change(m_ExitWatcherFrequency, m_ExitWatcherFrequency);
이 부분적으로 만 생각 작동합니다 - 그것은 CPU 스파이크를 중지,하지만 난 시스 인 터널 멋진 프로세스 모니터에서 내 프로세스를 보면, 내가 인해 DW20.exe 실행을 볼 수 있습니다 - "Microsoft 응용 프로그램 오류보고"프로그램. 그리고 그저 거기 앉아서 콘솔 앱이 메모리에 남아 있습니다.
연속적인 CPU 스파이크 및 출시되지 않은 메모리를 방지하기 위해 프로세스를 올바르게 종료하려면 어떻게해야합니까? 결국 이것은 개입없이 실행되어야합니다.
P. 부모 프로그램은 stdin을 통해 데이터를 전달하는 명령 줄 앱만 실행하도록 구성 할 수 있기 때문에 여기서는 Windows 서비스 또는 웹 서비스 대신 "장기 실행 프로그램"으로 명령 줄 응용 프로그램을 사용하고 있습니다. (궁금한 사람들에게는 외부 인증을 사용하는 ejabberd입니다.)
는편집 : 표준 입력에서 입력을 기다립니다
코드는 다음과 같습니다 부모가 종료 될 때 그 전에
// Read data from stdin
char[] charray = new char[maxbuflen];
read = Console.In.Read(charray, 0, 2);
내가 언급은 콘솔 응용 프로그램은 CPU에 미쳐 간다. 내가 Visual Studio에서 디버거를 첨부했는데, 사실, 여전히 Console.In.Read 행에 앉아 있습니다. 그런 다음 이론적으로 자체 모니터링 타이머가 트리거되어 부모가 사라 졌음을 확인하면 다른 스레드가 해당 Read() 행에있을 때 System.Environment.Exit (0)을 시도합니다.
+1은 CPU 스파이크를 설명합니다 –
흠, 좋은 점이 있습니다. 나는 CPU가 왜 스파이크를 일으키는 지 생각하기 위해 정말로 멈추지는 않았지만, Console.In.Read가 항상 0을 반환하기 때문에 지속적인 루프를 치는 것은 많은 의미를가집니다. – Matt
여기에서주의해야 할 점은 정상 작동 중에 0 바이트가 반환되면 콘솔 앱이 제대로 종료되지 않는다는 것입니다. –