Logic to kill a process over a period

I want my logic to be correct. I want to start a process in timeout seconds, if it runs longer, it should be killed immediately.

The completed flag should reliably indicate whether the process completed as intended, for example, has not been killed, and also not a failure or throwing an exception.

Also, I'm not sure if the check on process.HasExited correct. If process.WaitForExit() returns false and Kill() succeeds, will process.HasExited always be true? That would be my guess, but I wanted to confirm. Also, what if something can be done if kill () is other than what you register?

  using (process = new Process()) { process.EnableRaisingEvents = true; process.OutputDataReceived += new DataReceivedEventHandler(OnOutputDataReceived); process.ErrorDataReceived += new DataReceivedEventHandler(OnErrorDataReceived); process.Exited += new EventHandler(OnExited); process.StartInfo = startInfo; process.Start(); process.BeginOutputReadLine(); process.BeginErrorReadLine(); if (!process.WaitForExit(timeout)) { try { process.Kill(); } catch (Exception e) { LogError(e, MethodBase.GetCurrentMethod()); } finally { this.completed = false; } } else { if (process.HasExited) { this.code = process.ExitCode; this.completed = true; } else { this.completed = false; } } } 
+4
source share
4 answers

Yes, HasExited will always be true in your case.

According to MSDN ,

"A true value for HasExited indicates that the associated process terminated normally or abnormally . [...] The process may terminate regardless of your code. If you started the process using this component, the system automatically updates the HasExited value, even if the corresponding process exits independently .

However, if your process crashes and exits before your timeout, your code will set it to complete anyway. You might want to check the exit code, but it can have different meanings for each process:

 if (process.ExitCode != 0) { this.completed = false; } 

There are several approaches for failures here and here , but usually you cannot detect failures for all processes.

+4
source

We use the following in a .net console application

 private void InitTimer() { double lInterval = Convert.ToDouble(AppSettings("MaxExecutionTime")); lInterval = lInterval * 60 * 1000; tm = new System.Timers.Timer(lInterval); // global timer object tm.Elapsed += OnTimedEvent; tm.Enabled = true; } public void ThreadProc(object stateinfo) { // set error code here Environment.Exit(0); } private void OnTimedEvent(object source, ElapsedEventArgs e) { Threading.ThreadPool.QueueUserWorkItem(new Threading.WaitCallback(ThreadProc)); } 
+2
source

In C, you can set the OS alarm using the alarm function. When this expires, SIGALRM will be sent to your process, which kills it if the handler is not installed.

+1
source

You can use this . This is the C # wrapper over the JobObjects function. The idea is that (a low-level structure built into the library that I mentioned):

  • Create a job object.
  • Set the job object to a time limit of x seconds.
  • Create a process before resuming it, bringing it to the task object.
  • Resume the process.
  • The process will be killed by the operating system when time passes. Usually you get a notification using a return code without a zero or callback. The JobObject API itself allows you to receive callbacks, and is not sure about the C # shell.

Also, using job objects, you can limit memory usage. On the page, I mentioned that you can also find examples.

UPDATE

After I wrote the above statements, I found this Kill child process when the parent process was killed . They use JobObjects for another task, but the use of JobObjects should be the same as for your case.

+1
source

Source: https://habr.com/ru/post/1502931/


All Articles