Как закрыть входной поток движка IronPython, выполняющего скрипт? - PullRequest
0 голосов
/ 03 февраля 2010

Я создаю движок IronPython примерно так:

var engine = IronPython.Hosting.Python.CreateEngine();                
var scope = engine.CreateScope();

// my implementation of System.IO.Stream
var stream = new ScriptOutputStream(engine);
engine.Runtime.IO.SetOutput(stream, Encoding.UTF8);
engine.Runtime.IO.SetErrorOutput(stream, Encoding.UTF8);
engine.Runtime.IO.SetInput(stream, Encoding.UTF8);

var script = engine.CreateScriptSourceFromString(source, SourceCodeKind.Statements);
script.Execute(scope);

Переменная source представляет собой строку со следующим содержимым (операторы python):

import code
code.interact(None, None, 
        {
            '__name__' :  '__console__', 
            '__doc__'  :   None, 
        })

Поток размещается в форме Windows. Когда эта форма закроется, я хочу, чтобы переводчик ушел. Очевидно, я попытался закрыть поток в методе Read:

    /// <summary>
    /// Read from the _inputBuffer, block until a new line has been entered...
    /// </summary>
    public override int Read(byte[] buffer, int offset, int count)
    {

        if (_gui.IsDisposed)
        {
            return 0; // msdn says this indicates the stream is closed
        }

        while (_completedLines.Count < 1)
        {
            // wait for user to complete a line
            Application.DoEvents();
            Thread.Sleep(10);
        }
        var line = _completedLines.Dequeue();
        return line.Read(buffer, offset, count);
    }

Переменная-член _completedLines содержит очередь из MemoryStream объектов, представляющих строки, введенные пользователем до сих пор. _gui является ссылкой на форму окна - когда она удаляется, я почему-то хочу, чтобы механизм IronPython прекратил выполнение code.interact().

Возврат 0 из метода Read не работает (Read просто вызывается снова). Вызов одного из исключений из документации Read также не работает: он останавливает выполнение интерпретатора, но среда IDE прерывается в методе Read: (

Я также пытался вернуть ^Z (0x1a) и ^D (0x04) в буфер Read, так как они используются на консоли для выхода из интерпретатора, но это не работает вообще. ..

1 Ответ

1 голос
/ 03 февраля 2010

Мне понадобился второй взгляд, чтобы понять, что вы хотели, но это похоже на ошибку в IronPython. code.interact ожидает, что EOFError будет вызвано из встроенного raw_input, чтобы сигнализировать, что пора завершать цикл, но IronPython этого не делает - он просто возвращает пустую строку. Это IronPython выпуск № 22140 .

Вы можете попробовать выдать исключение EndOfStreamException, которое преобразуется в EOFError. Этого может быть достаточно, чтобы обмануть его.

...