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
Lepaskan: 2025-01-25 04:40:11
asal
306 orang telah melayarinya

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>
Salin selepas log masuk
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 Laman Web ini
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
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan