Rumah >pembangunan bahagian belakang >C++ >Bagaimanakah Saya Boleh Memastikan Proses Kanak-Kanak Tamat Apabila Proses Induk Berakhir dalam C#?

Bagaimanakah Saya Boleh Memastikan Proses Kanak-Kanak Tamat Apabila Proses Induk Berakhir dalam C#?

DDD
DDDasal
2025-01-25 04:40:11307semak imbas

How Can I Ensure Child Processes Terminate When the Parent Process Ends in C#?

c# Kesan penamatan proses bapa pada proses proses kanak -kanak

Dalam pembangunan perisian, tingkah laku proses kanak -kanak apabila proses induk ditamatkan adalah penting untuk mengekalkan kestabilan sistem. Apabila pelbagai sub -proses dijana oleh proses induk, adalah penting untuk memastikan bahawa mereka menamatkan proses induk. Artikel ini membincangkan masalah biasa: sub -proses yang dihasilkan oleh kelas

masih wujud walaupun aplikasi utama runtuh atau dipaksa oleh pengurus tugas.

System.Diagnostics.Process Objek operasi: Penyelesaian kepada struktur lapisan Bapa dan Anak

Untuk membina hubungan pergantungan antara proses kanak -kanak dan proses induk, fungsi yang disebut "objek operasi" boleh digunakan. Objek tugasan membolehkan hubungan penciptaan antara proses, dan penamatan objek operasi induk juga akan membawa kepada penamatan semua sub -proses yang berkaitan.

Kod berikut menunjukkan cara menggunakan objek kerja untuk menguruskan pergantungan proses:

Selepas membuat proses, hubungi kaedah

untuk mengaitkannya dengan objek operasi yang ditetapkan. Perhatikan bahawa definisi struktur yang diperlukan dan pelaksanaan antara muka
<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>
ditambah ke kod, serta pembebasan sumber yang betul.

Atas ialah kandungan terperinci Bagaimanakah Saya Boleh Memastikan Proses Kanak-Kanak Tamat Apabila Proses Induk Berakhir dalam C#?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn