Process.WaitForExit зависает даже без использования RedirectStandardError/RedirectStandardOutput

У нас есть служба, которая запускает процесс и ждет завершения процесса, когда служба остановлена /пользователь вызовов службы останавливается (чтобы остановить/убить процесс, запущенный службой).

Спорадически зависает process.waitForExit(TimeSpan).

Обратите внимание, что процесс, запущенный службой, - это процесс native process (C++/CLI), и служба находится на С#.

Ниже приведен фрагмент кода, который мы используем.

public class ApplicationProcessControl : IProcessControl
 {  
    private Process _proc;
    private const int ProcessIdleTimeout = 5000;

    public bool Start(string arguments)
    {
        if (IsAlive)
        {
            Log.TraceInfo("Application process already running. Killing it now...");
            _proc.Kill();
        }

        var eProcStarted = new Mutex(false, "Mutex111");

        _proc = new Process { EnableRaisingEvents = true, StartInfo = new ProcessStartInfo(_exePath, arguments) { RedirectStandardOutput = false,RedirectStandardError = false};
        _proc.Exited += OnProcessExited;

        _proc.Start();
        bool started;
        if(_proc == null)
        {
            Log.TraceInfo("Unable to start application process");
            started = false;
        }
        else
        {
            started = eProcStarted.WaitOne(ProcessIdleTimeout);

            if(started)
            {
                Log.TraceInfo($"Application process with id {_proc.Id} started successfully");
            }
        }
        eProcStarted.Dispose();
        return started;
    } 

    public void Kill()
    {
        _proc.Kill();
    }

    public bool WaitForProcessToExit(TimeSpan timeout)
    {
        return _proc.WaitForExit((int) timeout.TotalMilliseconds);
    }

    public event Action ProcessExited;

    private void OnProcessExited(object sender, EventArgs e)
    {
        var proc = sender as Process;

        if(proc != null)
        {
            proc.Exited -= OnProcessExited;

            if(proc.ExitCode == 0)
            {
                Log.TraceInfo("Application process exited gracefully");
            }
            else
            {
                Log.DeveloperWarning("Application process exited unexpectedly with code {0}", proc.ExitCode);
                OnProcessExited();
            }
        }
    }

    private void OnProcessExited()
    {
        Action handler = ProcessExited;
        handler?.Invoke();
    }
}

public interface IProcessControl
{
    bool IsAlive { get; }

    bool Start(string arguments);

    bool WaitForProcessToExit(TimeSpan timeout);

    void Kill();

    event Action ProcessExited;
}

public class ApplicationClientService: DisposableObject, IComponentService, ITaskControl, IUIControl,
        IDataProvider<AngleFlavors>, IApplicationCloseNotifier
{
    //...
    private readonly IProcessControl _procCtrl;

    public ApplicationClientService(IObjectProvider objPro)
    {
        //...
        _procCtrl.ProcessExited += OnApplicationProcessExited;              
    }

    public void Stop()
    {
        //...
        CleanUpAppProcess();
        //...
    }


    private void CleanUpAppProcess()
    {
        //...

        if(!_procCtrl.WaitForProcessToExit(TimeSpan.FromSeconds(5)))
        {
            _procCtrl.Kill();
        }
    }

    private void OnApplicationProcessExited()
    {
        if(!_isAppRunning)
        {
            return;
        }

        _isAppRunning = false;
        _autoLaunchRequested = false;
        RaiseApplicationClosed();
        Log.DeveloperWarning("Application process closed unexpectedly");
        Log.UserMessageApplicationClosedUnexpectedly();
        ...
    }

    protected virtual void RaiseApplicationClosed()
    {
        //AuditApplicationStop();
        //ApplicationClosed?.Invoke();
    }

}

Ответы