Heim > Backend-Entwicklung > C++ > Wie kann sichergestellt werden, dass untergeordnete Prozesse in C# beendet werden, wenn die übergeordnete Anwendung abstürzt?

Wie kann sichergestellt werden, dass untergeordnete Prozesse in C# beendet werden, wenn die übergeordnete Anwendung abstürzt?

Susan Sarandon
Freigeben: 2025-01-25 04:45:10
Original
273 Leute haben es durchsucht

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

Implementierung des Mechanismus in C#, damit der untergeordnete Prozess mit dem übergeordneten Prozess endet

Beim Erstellen eines Prozesses mit der Klasse System.Diagnostics.Process muss unbedingt sichergestellt werden, dass der untergeordnete Prozess auch beendet wird, wenn die übergeordnete Anwendung abstürzt. In einigen Fällen, beispielsweise beim Beenden einer Anwendung über den Task-Manager, erfolgt dieses Verhalten jedoch nicht automatisch.

Um dieses Problem zu lösen, können wir das vom Windows-Betriebssystem bereitgestellte „Jobobjekt“ nutzen. Indem wir ein Jobobjekt für die übergeordnete Anwendung erstellen und den untergeordneten Prozess darin registrieren, können wir Abhängigkeiten zwischen Prozessen herstellen. Dadurch wird sichergestellt, dass das Betriebssystem den untergeordneten Prozess automatisch beendet, wenn der übergeordnete Prozess beendet wird.

Implementierung des Jobobjekts

Der folgende Code zeigt, wie man ein Jobobjekt erstellt und ihm einen untergeordneten Prozess zuordnet:

<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>
Nach dem Login kopieren

Die Schlüsselzeile im Konstruktor lautet:

<code class="language-csharp">info.LimitFlags = 0x2000;</code>
Nach dem Login kopieren

Dadurch wird das Flag JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE gesetzt, das angibt, dass beim Schließen eines Jobs alle mit dem Job verbundenen Prozesse beendet werden sollen.

Nachdem Sie ein Jobobjekt erstellt haben, können Sie diesem mithilfe der Methode AddProcess einen untergeordneten Prozess zuordnen. Ein Beispiel ist wie folgt:

<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>
Nach dem Login kopieren

Durch die Registrierung untergeordneter Prozesse bei einem Jobobjekt stellen Sie sicher, dass diese automatisch beendet werden, auch wenn das Betriebssystem plötzlich beendet wird. Dem Code wurden Fehlerbehandlung und Ressourcenfreigabe hinzugefügt, wodurch die Robustheit und Zuverlässigkeit des Codes verbessert wird. Stellen Sie außerdem sicher, dass Sie die Excel-Interop-Bibliothek korrekt referenzieren.

Hinweis: Diese Methode basiert auf der vom Windows-Betriebssystem bereitgestellten Jobobjektfunktion und ist nur auf die Windows-Plattform anwendbar. Darüber hinaus müssen Sie die kernel32.dll-Deklaration (P/Invoke-Klasse) für Win32 hinzufügen. Dieser Teil wird im Code weggelassen und muss von Ihnen selbst ergänzt werden. Und Sie müssen potenzielle Ausnahmen behandeln, z. B. das Nichtvorhandensein eines Prozesses oder unzureichende Berechtigungen. Denken Sie abschließend daran, das COM-Objekt freizugeben, um Ressourcenlecks zu vermeiden.

Das obige ist der detaillierte Inhalt vonWie kann sichergestellt werden, dass untergeordnete Prozesse in C# beendet werden, wenn die übergeordnete Anwendung abstürzt?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage