Я проверил решение по комментариям на основе Task
- это полезно, когда у вас есть операция блокировки. Вы можете избежать блокировки вызова WaitForProcessExit()
и создать более простое решение.
Решение находится в форме оболочки.
public enum SafeProcessState { Exit = 1, Killed = 2 }
public class SafeProcess
{
private readonly Process process;
private readonly Func<bool> killPredicate;
public SafeProcess(Func<bool> killPredicate, Process process)
{
this.killPredicate = killPredicate;
this.process = process;
}
public async Task<SafeProcessState> WaitAsync()
{
var state = SafeProcessState.Exit;
while (true)
{
await Task.Delay(100);
if (this.killPredicate())
{
state = SafeProcessState.Killed;
if (this.process.HasExited == false)
{
this.process.Kill();
}
break;
}
else if (this.process.HasExited)
{
break;
}
}
return state;
}
}
Вот как вы можете использовать его в ASP NET MVC action (Not. NET CORE);
public async ...... ActionName()
{
var process = Process.Start("....");
var wrapper = new SafeProcess(() => HttpContext.Current.Response.IsClientConnected == false, process);
var state = await wrapper.WaitAsync();
}
В основном он ожидает (проверяя каждые 100 мс), что процесс завершается, или клиент отключается и возвращает информацию о выходе. причина - Exit
или Killed
.
Убивает процесс, если пользователь отключился.
Использование async / await Task.Delay
гарантирует, что мы освободим поток выполнения, и в течение 100 мс это делается исключительно из соображений производительности.
ПРИМЕЧАНИЕ : Вы можете получить в сценарий убийства уже вышедшего процесса, который вызовет исключение (у вас есть параллелизм между процессом и вашим действием asp net). Вам потребуется некоторая синхронизация между выполнением процесса и .Kill()
... или вы можете заключить вызов в try / catch.
Если вы выберете сценарий try / catch Забыли, обязательно запишите ситуацию.