Встраивание IronPython в приложение WinForms и прерывание выполнения - PullRequest
10 голосов
/ 27 мая 2010

ОБЩАЯ ИНФОРМАЦИЯ

МОЯ ПРОБЛЕМА

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

МОЙ ВОПРОС

  • Как можноЯ сделал так, что нажатие кнопки «стоп» фактически остановит выполнение введенного кода IronPython?

NOTES

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

1 Ответ

10 голосов
/ 27 мая 2010

Это в основном адаптация того, как консоль 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.

...