我有打開子進程的父進程。只有當父進程不再運行時,我需要執行一些功能。父進程和子進程的關係
知道父進程沒有運行的最佳方式是什麼?因爲它可以被劇烈終止,所以我不想讓一些功能在關閉事件中向我的子進程發送信號。
或只是爲了尋找我這樣的父進程:
在父做這一點,並把它傳遞給孩子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