Poprawne używanie Process

0

Natrafiłem dzisiaj na dziwną rzecz związaną z klasą Process.

Mam oto taki kod, który ma rozpocząć jakiś proces:

 
public void StartProcess(string fileName, 
            EventHandler endProcessHandler, 
            bool forceWaitForEnd = false)
{
    m_wasKilled = false;

    m_process = new Process();
    m_process.StartInfo.FileName = fileName;
    m_process.StartInfo.UseShellExecute = false;
    m_process.EnableRaisingEvents = true;

    m_process.Exited += new EventHandler(OnProcessExited);
    m_additionalEndProcessHandler = endProcessHandler;

    m_process.Start();

    if (forceWaitForEnd)
        m_process.WaitForExit();
}

W prawdziwym kodzie mam jeszcze przekazywanie argumentów i przekierowanie output stream i error stream, ale dla czytelności nie pokazałem tu tego.

Mam też gdzieś tam zdarzenie OnProcessExited:

 
void OnProcessExited(object sender, EventArgs e)
{
    if (!m_wasKilled)
    {
        DisposeProcess();
        if (m_additionalEndProcessHandler != null)
            m_additionalEndProcessHandler(this, e);
    }
}

W metodzie DisposeProcess wywołuję m.in. m_process.Dispose, bo jak jest napisane w dokumentacji (https://msdn.microsoft.com/pl-pl/library/system.diagnostics.process%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396)

This type implements the IDisposable interface. When you have finished using the type, you should dispose of it either directly or indirectly. To dispose of the type directly, call its Dispose method in a try/catch block. To dispose of it indirectly, use a language construct such as using (in C#) or Using (in Visual Basic).

Jednak pierwsza dziwna rzecz jest taka, że Microsoft w swoich przykładach, mimo że tworzy obiekt Process za pomocą new, to nigdzie nie wywołuje Dispose (pośrednio, czy też bezpośrednio). Co więcej, efektem działania mojego kodu jest to, że owszem, aplikacja startuje, potem czeka na zakończenie. Gdy aplikacja się kończy, wywoływane jest zdarzenie OnProcessExited, ale uwaga, w tym momencie m_process jest nullem :| Wygląda na to, że obiekt klasy Process, po zakończeniu powiązanego procesu sam się niszczy? Czy to jest poprawne działanie? Czy tak powinno być?

[dopisane]
Zauważyłem, że OnProcessExited jest wywoływane dwa razy.

0

Rozwiązaniem CHYBA jest to, żeby nie mieszać WaitForExit ze zdarzeniem Exited. Bo wtedy zdarzenie Exited jest wywoływane dwa razy - za pierwszym razem z wątku, w którym proces został utworzony, za drugim razem z jakiegoś dziwnego dodatkowego wątku tworzonego przez .NET.

1 użytkowników online, w tym zalogowanych: 0, gości: 1