我有打开子进程的父进程。只有当父进程不再运行时,我需要执行一些功能。父进程和子进程的关系
知道父进程没有运行的最佳方式是什么?因为它可以被剧烈终止,所以我不想让一些功能在关闭事件中向我的子进程发送信号。
或只是为了寻找我这样的父进程:
在父做这一点,并把它传递给孩子Process.GetCurrentProcess().Id
而在孩子的每几毫秒检查这一个
Process localById = Process.GetProcessById(1234);
任何想法?建议..
我有打开子进程的父进程。只有当父进程不再运行时,我需要执行一些功能。父进程和子进程的关系
知道父进程没有运行的最佳方式是什么?因为它可以被剧烈终止,所以我不想让一些功能在关闭事件中向我的子进程发送信号。
或只是为了寻找我这样的父进程:
在父做这一点,并把它传递给孩子Process.GetCurrentProcess().Id
而在孩子的每几毫秒检查这一个
Process localById = Process.GetProcessById(1234);
任何想法?建议..
下面是一个简单的例子,如何使用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窗体应用程序中,您不需要使用它,因为您的程序将处于消息循环中,并且只有在关闭它时才会退出。
我已经使用了Process.Exited示例。真的非常感谢您的好解释。 – 2010-07-26 15:54:39
底层的Win32进程句柄是可等待的,并且将在进程退出时发出信号。
在本地代码:
DWORD res = WaitForSIngleObject(hProcess, INFINITE);
if (res == WAIT_OBJECT_0) {
// process has exited.
}
在本机代码,你需要要么创建的WaitHandle
定制亚型工艺处理,或使用的P/Invoke。 P/Invoke的缺点是难以合并(使用WaitForMultipleObjects
多个等待,所以你不用专门用来等待一件事的线程)。
感谢0xA3:只要使用Process.WaitForExit
(有一个超时,以避免无限期等待过载,并没有这样做对你的UI线程)。
对不起,不是真的想去本地代码。 – 2010-07-26 08:04:20
@Night Walker:不需要这么做,只需使用'Process.WaitForExit'。可能最好在一个单独的线程。 – 2010-07-26 08:15:23
@ 0xA3:有时MS已经为你做了工作...... – Richard 2010-07-26 08:29:36
当父进程启动子进程时,通过命令行参数将父进程ID传递给子进程。
然后在子进程中,使用Process.GetProcessById(int)
获取父进程并使用Process.WaitForExit()
。或者,您可以使用Process.Exited
事件在父进程退出时收到通知(请记住将Process.EnableRaisingEvents
设置为true
,否则将不会引发该事件)。
我制作了一个子进程管理库,其中父进程和子进程由于双向WCF管道而受到监视。如果子进程终止或父进程终止,则通知对方。 还有一个可用的调试器助手,它可以将VS调试器自动附加到启动的子进程。
双向WCF通道是可扩展的,您可以处理进程启动和进程终止事件。
项目选址:
http://www.crawler-lib.net/child-processes
的NuGet软件包:
https://www.nuget.org/packages/ChildProcesses https://www.nuget.org/packages/ChildProcesses.VisualStudioDebug/
呃...通常它的父进程。除非你真的认识到你的过程的性别。干杯。 – 2010-07-26 07:49:07
@AOI Karasu:大声笑,好点,我冒昧地改变这一点(如果性别很重要,请回复我的变化,Night Walker)。 – Abel 2010-07-26 07:53:43
我刚刚发布了一个用于.NET的子进程库。 http://childprocess.codeplex.com/ – 2012-06-14 07:46:31