如何在单独的 AppDomain 中托管 IronPython 引擎?
我已经尝试过明显的方法:
var appDomain = AppDomain.CreateDomain("New Domain");
var engine = IronPython.Hosting.Python.CreateEngine(appDomain); // boom!
但我收到以下错误消息: 类型未解析为成员 'Microsoft.Scripting.Hosting.ScriptRuntimeSetup,Microsoft.Scripting, Version=0.9.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 '.
到目前为止,谷歌搜索此错误尚未证明有成效...
编辑#1:
我尝试通过将相关内容复制到新的控制台应用程序来创建一个最小的复制项目:
using System;
using Microsoft.Scripting;
namespace PythonHostSamle
{
class Program
{
static void Main(string[] args)
{
AppDomain sandbox = AppDomain.CreateDomain("sandbox");
var engine = IronPython.Hosting.Python.CreateEngine(sandbox);
var searchPaths = engine.GetSearchPaths();
searchPaths.Add(@"C:\Python25\Lib");
searchPaths.Add(@"C:\RevitPythonShell");
engine.SetSearchPaths(searchPaths);
var scope = engine.CreateScope();
//scope.SetVariable("revit", _application);
//engine.Runtime.IO.SetOutput(new ScriptOutputStream(_instance), Encoding.UTF8);
//engine.Runtime.IO.SetErrorOutput(new ScriptOutputStream(_instance), Encoding.UTF8);
var script = engine.CreateScriptSourceFromString("print 'hello, world!'", SourceCodeKind.Statements);
script.Execute(scope);
Console.ReadKey();
}
}
}
这有效正如预期的那样!
因此,我得出的结论是,我收到的错误与我注释掉的其中一行有关:添加到引擎的范围包含一个我几乎无法控制的对象 - 对插件的引用该软件旨在在(Autodesk Revit Architecture 2010)中运行。
也许试图通过这就是造成错误的原因?
有没有办法通过代理来代替? (必须查找.NET远程处理...)
编辑#2:
我已将问题简化为通过无法代理到其他AppDomain的范围传递对象:添加的所有对象到在不同 AppDomain 中运行的 IronPython 解释器的范围必须以某种方式进行编组,因此必须扩展 MarshalByRefObject
或 Serialized
。
I have tried the obvious:
var appDomain = AppDomain.CreateDomain("New Domain");
var engine = IronPython.Hosting.Python.CreateEngine(appDomain); // boom!
But I am getting the following error message: Type is not resolved for member 'Microsoft.Scripting.Hosting.ScriptRuntimeSetup,Microsoft.Scripting, Version=0.9.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'.
Googling for this error has not proved fruitful sofar...
EDIT #1:
I tried to create a minimal reproducing project by copying the relevant stuff to a new Console Application:
using System;
using Microsoft.Scripting;
namespace PythonHostSamle
{
class Program
{
static void Main(string[] args)
{
AppDomain sandbox = AppDomain.CreateDomain("sandbox");
var engine = IronPython.Hosting.Python.CreateEngine(sandbox);
var searchPaths = engine.GetSearchPaths();
searchPaths.Add(@"C:\Python25\Lib");
searchPaths.Add(@"C:\RevitPythonShell");
engine.SetSearchPaths(searchPaths);
var scope = engine.CreateScope();
//scope.SetVariable("revit", _application);
//engine.Runtime.IO.SetOutput(new ScriptOutputStream(_instance), Encoding.UTF8);
//engine.Runtime.IO.SetErrorOutput(new ScriptOutputStream(_instance), Encoding.UTF8);
var script = engine.CreateScriptSourceFromString("print 'hello, world!'", SourceCodeKind.Statements);
script.Execute(scope);
Console.ReadKey();
}
}
}
This works as expected!
I am thus left to conclude that the error I am getting is related to one of the lines I commented out: The scope added to the engine contains an object I have little control over - a reference to a plugin host this software is intended to run in (Autodesk Revit Architecture 2010).
Maybe trying to pass that is what is creating the error?
Is there a way to pass a proxy instead? (will have to look up .NET remoting...)
EDIT #2:
I have whittled the problem down to passing an object via the scope that does cannot be proxied to the other AppDomain: All objects added to the scope of an IronPython interpreter running in a different AppDomain will have to be marshaled somehow and must thus either extend MarshalByRefObject
or be Serializable
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
只需创建您自己的引导类,该类将在新的 AppDomain 中运行,并在那里进行 IronPyton 的初始化,它能解决问题吗?
Just create your own bootstrapping class that will run in a new AppDomain and will do the initialization of IronPyton there, will it solve the prob?