C# The impact of the termination of the father process on the process of the child process
In software development, the behavior of the child process when the parent process is terminated is critical to maintaining the stability of the system. When multiple sub -processes are generated by the parent process, it is important to ensure that they are terminating with the parent process. This article discusses a common problem: the sub -processes generated by the
class are still existed even when the main application collapses or is forced by the task manager.
System.Diagnostics.Process
The object of the operation: the solution to the layer structure of the father and son
In order to build the dependency relationship between the child process and the parent process, the function called "operation object" can be used. The assignment object allows the creation relationship between processes, and the termination of the parent operation object will also lead to the termination of all associated sub -processes.
The following code demonstrates how to use the work object to manage the process dependence:
After creating the process, call the
method to associate it with the established operation objects. Note that the necessary structure definition and the implementation of the<code class="language-csharp">using System; using System.Runtime.InteropServices; using System.Diagnostics; public class Job : IDisposable { [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] static extern IntPtr CreateJobObject(IntPtr a, string lpName); [DllImport("kernel32.dll")] static extern bool SetInformationJobObject(IntPtr hJob, JobObjectInfoType infoType, IntPtr lpJobObjectInfo, uint cbJobObjectInfoLength); [DllImport("kernel32.dll", SetLastError = true)] static extern bool AssignProcessToJobObject(IntPtr job, IntPtr process); private IntPtr _handle; private bool _disposed = false; public Job() { _handle = CreateJobObject(IntPtr.Zero, null); JOBOBJECT_BASIC_LIMIT_INFORMATION info = new JOBOBJECT_BASIC_LIMIT_INFORMATION(); info.LimitFlags = 0x2000; // JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE JOBOBJECT_EXTENDED_LIMIT_INFORMATION extendedInfo = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION(); extendedInfo.BasicLimitInformation = info; int length = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION)); IntPtr extendedInfoPtr = Marshal.AllocHGlobal(length); Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false); if (!SetInformationJobObject(_handle, JobObjectInfoType.ExtendedLimitInformation, extendedInfoPtr, (uint)length)) throw new Exception($"无法设置信息。错误:{Marshal.GetLastWin32Error()}"); Marshal.FreeHGlobal(extendedInfoPtr); } public void AddProcess(Process process) { if (!AssignProcessToJobObject(_handle, process.Handle)) throw new Exception($"无法将进程分配到作业对象。错误:{Marshal.GetLastWin32Error()}"); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (_disposed) return; if (disposing) { } Close(); _disposed = true; } public void Close() { if (_handle != IntPtr.Zero) { Win32.CloseHandle(_handle); _handle = IntPtr.Zero; } } } internal static class Win32 { [DllImport("kernel32.dll")] internal static extern bool CloseHandle(IntPtr hObject); } // 必要的结构体定义 (根据需要补充完整) enum JobObjectInfoType { ExtendedLimitInformation = 9 } [StructLayout(LayoutKind.Sequential)] internal struct IO_COUNTERS { public UInt64 ReadOperationCount; public UInt64 WriteOperationCount; public UInt64 OtherOperationCount; public UInt64 ReadTransferCount; public UInt64 WriteTransferCount; public UInt64 OtherTransferCount; } [StructLayout(LayoutKind.Sequential)] internal struct JOBOBJECT_BASIC_LIMIT_INFORMATION { public Int64 PerProcessUserTimeLimit; public Int64 PerJobUserTimeLimit; public UInt32 LimitFlags; public UIntPtr MinimumWorkingSetSize; public UIntPtr MaximumWorkingSetSize; public UInt32 ActiveProcessLimit; public UInt32 Affinity; public UInt32 PriorityClass; public UInt32 SchedulingClass; } [StructLayout(LayoutKind.Sequential)] internal struct JOBOBJECT_EXTENDED_LIMIT_INFORMATION { public JOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimitInformation; public IO_COUNTERS IoInfo; public UInt64 ProcessMemoryLimit; public UInt64 JobMemoryLimit; public UInt64 PeakProcessMemoryUsed; public UInt64 PeakJobMemoryUsed; }</code>
The above is the detailed content of How Can I Ensure Child Processes Terminate When the Parent Process Ends in C#?. For more information, please follow other related articles on the PHP Chinese website!