Внедрение IronPython в приложение WinForms и прерывание выполнения

ПРЕДПОСЫЛКИ

МОЯ ПРОБЛЕМА

  • Пользователям необходимо будет прервать выполнение своего кода
  • Другими словами, им нужно что-то вроде возможности ударить CTRL-C, чтобы остановить выполнение при запуске Python или IronPython из cmdline
  • Я хочу добавить кнопку в winform, которая при нажатии останавливает выполнение, но я не уверен, как это сделать.

МОЙ ВОПРОС

  • Как я могу сделать так, чтобы нажатие кнопки "Стоп" фактически остановило выполнение использования введенного кода IronPython?

ПРИМЕЧАНИЯ

  • Примечание. Я не хочу просто отбрасывать эту "сессию". Я все еще хочу, чтобы пользователь мог взаимодействовать с сеансом и получать доступ к любым результатам, которые были доступны до его остановки.
  • Я предполагаю, что мне нужно будет выполнить это в отдельном потоке, любое руководство или образец кода, делая это правильно, будут оценены.

Ответ 1

Это в основном адаптация того, как консоль IronPython обрабатывает Ctrl-C. Если вы хотите проверить источник, он находится в BasicConsole и CommandLine.Run.

Сначала запустите движок IronPython в отдельном потоке (как вы предполагали). Когда вы идете запустить код пользователя, оберните его в блок try ... catch(ThreadAbortException):

var engine = Python.CreateEngine();
bool aborted = false;
try {
    engine.Execute(/* whatever */);
} catch(ThreadAbortException tae) {
    if(tae.ExceptionState is Microsoft.Scripting.KeyboardInterruptException) {
        Thread.ResetAbort();
        aborted = true;
    } else { throw; }
}

if(aborted) {
    // this is application-specific
}

Теперь вам нужно будет поддерживать ссылку на поток IronPython. Создайте обработчик кнопки в своей форме и вызовите Thread.Abort().

public void StopButton_OnClick(object sender, EventArgs e) {
    pythonThread.Abort(new Microsoft.Scripting.KeyboardInterruptException(""));
}

Аргумент KeyboardInterruptException позволяет потоку Python захватывать ThreadAbortException и обрабатывать его как KeyboardInterrupt.