Maison > développement back-end > C++ > Comment s'assurer que les processus enfants se terminent lorsque l'application parent se bloque en C #?

Comment s'assurer que les processus enfants se terminent lorsque l'application parent se bloque en C #?

Susan Sarandon
Libérer: 2025-01-25 04:45:10
original
269 Les gens l'ont consulté

How to Ensure Child Processes Terminate When the Parent Application Crashes in C#?

Implémentation du mécanisme en C# pour que le processus enfant se termine avec le processus parent

Lors de la création d'un processus à l'aide de la classe System.Diagnostics.Process, il est crucial de s'assurer que le processus enfant se termine également si l'application parent plante. Cependant, dans certains cas, comme lors de la fermeture d'une application via le Gestionnaire des tâches, ce comportement n'est pas automatique.

Afin de résoudre ce problème, nous pouvons utiliser le "job object" fourni par le système d'exploitation Windows. En créant un objet de travail pour l'application parent et en y enregistrant le processus enfant, nous pouvons établir des dépendances entre les processus. Cela garantit que le système d'exploitation met automatiquement fin au processus enfant lorsque le processus parent se termine.

Mise en œuvre de l'objet de travail

Le code suivant montre comment créer un objet de travail et lui associer un processus enfant :

<code class="language-csharp">public class Job : IDisposable
{
    private IntPtr m_handle;
    private bool m_disposed = false;

    public Job()
    {
        m_handle = CreateJobObject(IntPtr.Zero, null); // 修正:使用IntPtr.Zero

        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(m_handle, JobObjectInfoType.ExtendedLimitInformation, extendedInfoPtr, (uint)length))
            throw new Exception($"无法设置信息。错误代码:{Marshal.GetLastWin32Error()}"); // 使用插值字符串

        Marshal.FreeHGlobal(extendedInfoPtr); // 释放非托管内存
    }

    public bool AddProcess(IntPtr handle)
    {
        return AssignProcessToJobObject(m_handle, handle);
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (m_disposed)
            return;

        if (disposing) { }

        Close();
        m_disposed = true;
    }

    public void Close()
    {
        Win32.CloseHandle(m_handle);
        m_handle = IntPtr.Zero;
    }
}</code>
Copier après la connexion

La ligne clé du constructeur est :

<code class="language-csharp">info.LimitFlags = 0x2000;</code>
Copier après la connexion

Ceci définit l'indicateur JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE, qui spécifie que lorsqu'un travail est fermé, tous les processus associés au travail doivent se terminer.

Après avoir créé un objet job, vous pouvez lui associer un processus enfant à l'aide de la méthode AddProcess. Un exemple est le suivant :

<code class="language-csharp">using Microsoft.Office.Interop.Excel; // 确保引用了Excel互操作库

// ...其他代码...

Excel.Application app = new Excel.ApplicationClass();

uint pid = 0;
Win32.GetWindowThreadProcessId(new IntPtr(app.Hwnd), out pid);
Process process = Process.GetProcessById((int)pid);
job.AddProcess(process.Handle);

// ...其他代码...

// 记得释放COM对象
Marshal.ReleaseComObject(app);
app = null;

// ...其他代码...</code>
Copier après la connexion

En enregistrant les processus enfants avec un objet de travail, vous vous assurez qu'ils sont automatiquement terminés même si le système d'exploitation s'arrête soudainement. La gestion des erreurs et la libération des ressources ont été ajoutées au code, améliorant ainsi la robustesse et la fiabilité du code. Assurez-vous également de référencer correctement la bibliothèque interop Excel.

Remarque : Cette méthode s'appuie sur la fonction d'objet de travail fournie par le système d'exploitation Windows et n'est applicable qu'à la plate-forme Windows. De plus, vous devez ajouter la déclaration kernel32.dll (classe P/Invoke) pour Win32. Cette partie est omise dans le code et doit être complétée par vous-même. Et vous devez gérer des exceptions potentielles, telles que l'inexistence de processus ou des autorisations insuffisantes. Enfin, pensez à libérer l'objet COM pour éviter les fuites de ressources.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal