如何关闭执行脚本的IronPython引擎的输入流?

时间:2010-02-03 14:52:21

标签: .net ironpython stream

我正在或多或少地创建一个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是对windows窗体的引用 - 当它被释放时,我不知何故希望IronPython引擎停止执行code.interact()

来自0方法的Read返回无效(仅Read再次调用)。从documentation of Read中提出一个例外也不起作用:它确实停止执行解释器,但IDE在Read方法内部中断:(

我也试过在^Z的缓冲区中返回^D(0x1a)和Read(0x04),因为这些在控制台上用来退出解释器,但是根本不工作......

1 个答案:

答案 0 :(得分:1)

我花了第二眼看出你想要的东西,但这看起来像是IronPython中的一个错误。 code.interact期望从raw_input内置引发EOFError以表示循环结束的时间,但IronPython不会这样做 - 它只返回一个空字符串。这是IronPython issue #22140

您可以尝试抛出EndOfStreamException,它会转换为EOFError。这可能足以欺骗它。