Я управляю скрипучим старым симулятором FORTRAN из графического интерфейса VB.NET, используя перенаправленный ввод-вывод для связи с исполняемым файлом симулятора. Графический интерфейс пользователя открывает окно «Состояние» с индикатором выполнения, расчетным временем и кнопкой «СТОП» (Button_Stop
).
Теперь я хочу, чтобы Button_Stop
немедленно завершил процесс симулятора. Очевидный способ сделать это - вызвать Kill()
для объекта Child
Process. Это дает исключение, если оно выполнено после завершения процесса, но я могу проверить, завершен ли процесс, прежде чем пытаться его уничтожить, верно?
ОК, поэтому, когда я нажимаю кнопку, я делаю следующее:
If Not Child.HasExited Then
Child.Kill()
Button_Stop.Enabled = False
End If
Однако, что если произойдет выход из процесса между тестом и вызовом Kill()
? В этом случае я получаю исключение.
Следующее, что мне пришло в голову, было то, что я могу сделать Button_Stop.Enabled = False
в обработчике Process.Exited
и, таким образом, предотвратить вызов Child.Kill()
в обработчике Button_Stop.Clicked
. Но поскольку обработчик Process.Exited
вызывается в другом потоке, все равно остается следующее возможное чередование:
- Дочерний процесс завершается.
Process.Exited
пожары, звонки Invoke
для планирования Button_Stop.Enabled = False
- Пользователь нажимает
Button_Stop
, вызывая Child.Kill()
Button_Stop.Enabled = False
на самом деле происходит.
На шаге 3 будет выдано исключение.
Как убить процесс без каких-либо условий гонки? Я думаю об этом совершенно неправильно?