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

Место общения программистов C#
Anonymous
Process.WaitForExit зависает даже без использования RedirectStandardError/RedirectStandardOutput

Сообщение Anonymous »

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

Случайно процесс.waitForExit(TimeSpan) зависает.

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

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

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, 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();
}

}


Подробнее здесь: https://stackoverflow.com/questions/502 ... irectstand

Вернуться в «C#»