Does process.kill () terminate WaitForExit () (no time limit)

I have a process that runs in the background and has WaitForExit() , since the duration can change, and I need to wait until it ends. In some cases, I need to finish it before it finishes, and I run the .Kill() command through the class event. The .HasExited property changes to true, but the code never gets the WaitForExit() string.

 public class MyProcess: Process { private bool exited; public MyProcess() { ... } public void Start(args...) { try { base.StartInfo.FileName = ... base.StartInfo.Arguments = ... base.StartInfo.RedirectStandardOutput = true; base.StartInfo.UseShellExecute = false; base.StartInfo.CreateNoWindow = true; base.EnableRaisingEvents = true; base.Exited += new EventHandler(MyProcessCompleted); base.OutputDataReceived += new DataReceivedEventHandler(outputReceived); base.Start(); this.exited = false; base.BeginOutputReadLine(); while (!this.exited) { if () { ... } else { base.WaitForExit(); ---- after the process is killed, it never gets past this line. } ... } } catch (Exception ex) { ... } } private void MyProcessCompleted(object sender, System.EventArgs e) { exited = true; ... } private void outputReceived(object sender, DataReceivedEventArgs e) { ... } //Subscription to cancel event public void ProcessCanceled(object sender, EventArgs e) { ... if (!exited) { base.Kill(); } } } 

\

UPDATE:

My process launches a java client to transfer files and performs the transfer. The process appears in the task manager, but Kill() does not end it. Since I really don’t care about completing the process, but I need my program to go to the next “task”, I added Close() right after Kill() , which releases WaitForExit and allows my code to “move”, Terminating the process at an early stage will be rare in my application, but I still need to work on it, so this implementation will have to be done.

}

+4
source share
2 answers

WaitForExit is a direct OS call to wait for a process handle to become a signal. When the process ends, WaitForExit ends. Kill is a direct call to TerminateProcess , which is killed without any questions. When used correctly, WaitForExit will return upon completion of Kill .

So there is another error in your code. Create a simpler reproduction and you will see that the problem disappears. The error is hidden in the complexity of your code.

Or, WaitForExit back, but you did not notice it. Or Kill never executed or never executed. Again, simplifying the code will reveal the problem. Can you wrap it on 5 lines? I doubt you can, but I will look again if you do.

Try the following:

 Process p = Process.Start("notepad.exe"); Task.Factory.StartNew(() => { Thread.Sleep(1000); p.Kill(); }); p.WaitForExit(); 

Update:

In the comments, you pointed out that killing ping does work, but there is no way to kill your special process. The reason for this is usually not canceled. The Windows kernel supports processes until all IOs are completed. The good news is that the process will finally disappear and the code will not return after Kill . The bad news is that resource cleanup is not complete.

Now you need to make sure your code can move, although WaitForExit not returned. To do this, I installed ManualResetEvent after completing Kill . And instead of calling WaitForExit you will get a process handle using the Process.Handle property and wait for one of the two waiting devices to become a signal. See what WaitForExit does internally to see how you could implement this yourself (I would copy the ProcessWaitHandle class, which is internal).

A simpler solution would be to call WaitForExit(TimeSpan.FromMilliseconds(100)) in a loop and check the exited flag each time.

+7
source

You would try a cleaner code (I think). testing.....

 Process proc = null; //Kill process after 3 seconds Task.Run(() => { Task.Delay(3000).Wait(); if(proc!=null && proc.HasExited==false) proc.Kill(); }); var psi = new ProcessStartInfo() { FileName = "ping.exe", Arguments = "-t 127.0.0.1", RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true, }; proc = new Process(); proc.StartInfo = psi; proc.OutputDataReceived += (s,e) => { Console.WriteLine(e.Data); }; proc.Start(); proc.BeginOutputReadLine(); proc.WaitForExit(); Console.WriteLine("**killed**"); 
0
source

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


All Articles