2010-07-26 131 views
2

我有打开子进程的父进程。只有当父进程不再运行时,我需要执行一些功能。父进程和子进程的关系

知道父进程没有运行的最佳方式是什么?因为它可以被剧烈终止,所以我不想让一些功能在关闭事件中向我的子进程发送信号。

或只是为了寻找我这样的父进程:

在父做这一点,并把它传递给孩子Process.GetCurrentProcess().Id 而在孩子的每几毫秒检查这一个

Process localById = Process.GetProcessById(1234); 

任何想法?建议..

+2

呃...通常它的父进程。除非你真的认识到你的过程的性别。干杯。 – 2010-07-26 07:49:07

+0

@AOI Karasu:大声笑,好点,我冒昧地改变这一点(如果性别很重要,请回复我的变化,Night Walker)。 – Abel 2010-07-26 07:53:43

+0

我刚刚发布了一个用于.NET的子进程库。 http://childprocess.codeplex.com/ – 2012-06-14 07:46:31

回答

4

下面是一个简单的例子,如何使用Process.WaitForExit检查其ID已经通过在命令行上的父进程:

using System; 
using System.Diagnostics; 
using System.Threading; 

class Program 
{ 
    static AutoResetEvent _autoResetEvent; 

    static void Main(string[] args) 
    { 
     int parentProcessId = int.Parse(args[0]); 

     _autoResetEvent = new AutoResetEvent(false); 

     WaitCallback callback = delegate(object processId) { CheckProcess((int)processId); }; 
     ThreadPool.QueueUserWorkItem(callback, parentProcessId); 

     _autoResetEvent.WaitOne(); 
    } 

    static void CheckProcess(int processId) 
    { 
     try 
     { 
      Process process = Process.GetProcessById(processId); 
      process.WaitForExit(); 
      Console.WriteLine("Process [{0}] exited.", processId); 
     } 
     catch (ArgumentException) 
     { 
      Console.WriteLine("Process [{0}] not running.", processId); 
     } 

     _autoResetEvent.Set(); 
    } 
} 

使用Process.Exited事件可以这样进行:

using System; 
using System.Diagnostics; 
using System.Threading; 

class Program 
{ 
    static AutoResetEvent _autoResetEvent; 

    static void Main(string[] args) 
    { 
     int parentProcessId = int.Parse(args[0]); 
     Process process = Process.GetProcessById(parentProcessId); 
     process.EnableRaisingEvents = true; 
     process.Exited += new EventHandler(process_Exited); 

     _autoResetEvent = new AutoResetEvent(false); 
     _autoResetEvent.WaitOne(); 
    } 

    static void process_Exited(object sender, EventArgs e) 
    { 
     Console.WriteLine("Process exit event triggered."); 
     _autoResetEvent.Set(); 
    } 
} 

请注意,在这两个样本中,AutoResetEvent的目的仅仅是为了防止您的主线程退出。在Windows窗体应用程序中,您不需要使用它,因为您的程序将处于消息循环中,并且只有在关闭它时才会退出。

+0

我已经使用了Process.Exited示例。真的非常感谢您的好解释。 – 2010-07-26 15:54:39

4

底层的Win32进程句柄是可等待的,并且将在进程退出时发出信号。

在本地代码:

DWORD res = WaitForSIngleObject(hProcess, INFINITE); 
if (res == WAIT_OBJECT_0) { 
    // process has exited. 
} 

在本机代码,你需要要么创建的WaitHandle定制亚型工艺处理,或使用的P/Invoke。 P/Invoke的缺点是难以合并(使用WaitForMultipleObjects多个等待,所以你不用专门用来等待一件事的线程)。


感谢0xA3:只要使用Process.WaitForExit(有一个超时,以避免无限期等待过载,并没有这样做对你的UI线程)。

+0

对不起,不是真的想去本地代码。 – 2010-07-26 08:04:20

+1

@Night Walker:不需要这么做,只需使用'Process.WaitForExit'。可能最好在一个单独的线程。 – 2010-07-26 08:15:23

+0

@ 0xA3:有时MS已经为你做了工作...... – Richard 2010-07-26 08:29:36

0

当父进程启动子进程时,通过命令行参数将父进程ID传递给子进程。

然后在子进程中,使用Process.GetProcessById(int)获取父进程并使用Process.WaitForExit()。或者,您可以使用Process.Exited事件在父进程退出时收到通知(请记住将Process.EnableRaisingEvents设置为true,否则将不会引发该事件)。

0

我制作了一个子进程管理库,其中父进程和子进程由于双向WCF管道而受到监视。如果子进程终止或父进程终止,则通知对方。 还有一个可用的调试器助手,它可以将VS调试器自动附加到启动的子进程。

双向WCF通道是可扩展的,您可以处理进程启动和进程终止事件。

项目选址:

http://www.crawler-lib.net/child-processes

的NuGet软件包:

https://www.nuget.org/packages/ChildProcesses https://www.nuget.org/packages/ChildProcesses.VisualStudioDebug/