如何在 C#.net 中全局初始化 REngine?
How to initialize REngine globally in C#.net?
我在我的 c# 项目中使用 R.Net 和 R.Net.Community 包来启用 R 脚本。我有一个 c# class 如下:
foreach(var item in list)
{
callR(item);
}
和另一个 class 到 运行 R 脚本中的方法:
CallR(int item)
{
//init the R engine
REngine.SetEnvironmentVariables();
engine = REngine.GetInstance();
engine.Initialize();
//Perform R
engine.SetSymbol("data", item);
engine.Evaluate("data<-data*data");
//engine.dispose
//Cannot use engine.dispose as re initialization of engine then, is not possible
}
编辑
我还有另外三分之一 class 调用相同的 R 方法。如果我在循环的 class 中实例化它,那么如何在此 class?
中使用该初始化
问题:
此代码在本地运行良好,但是在将其部署在服务器上时,它会中断并给出异常:"library stats could not be loaded".
在更深入的搜索中,我发现 this 说是多次初始化 Rengine 导致了这个问题。
因此我的问题是如何在应用程序启动时仅初始化 Rengine 一次,并在像我上面的代码这样的场景中使用它的实例?
您可以修改 CallR class 以拥有 REngine class 的单个实例,并通过仅初始化一次的方法获取它,例如
public static REngine engine = null;
public static REngine GetInitiazedREngine()
{
if (engine==null)
{
REngine.SetEnvironmentVariables();
engine = REngine.GetInstance();
engine.Initialize();
}
return engine;
}
CallR(int item)
{
//Get the initialized R Engine
REngine initializedEngine=GetInitiazedREngine();
//Perform R
initializedEngine.SetSymbol("data", item);
initializedEngine.Evaluate("data<-data*data");
//engine.dispose
//Cannot use engine.dispose as re initialization of engine then, is not possible
}
我认为更好的做法是使用单调模式,如下所示:
public class RNetEngine : IDisposable
{
private bool _disposed;
private REngine _rEngine;
private static readonly object Lock = new object();
private REngine Engine
{
get
{
if (_rEngine == null)
{
lock (Lock)
{
if (_rEngine == null)
{
_rEngine = REngine.GetInstance();
}
}
}
return _rEngine;
}
}
public void Evaluate(string expression)
{
Engine.Evaluate(expression);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (_disposed)
{
return;
}
if (disposing)
{
if (_rEngine != null && !_rEngine.Disposed)
{
_rEngine.Dispose();
}
}
_disposed = true;
}
}
这将使您保持线程安全并在需要时进行处置。我已经将它与 Castle.Windsor 单身人士的生活方式一起使用,所以它不是静态的。
我在我的 c# 项目中使用 R.Net 和 R.Net.Community 包来启用 R 脚本。我有一个 c# class 如下:
foreach(var item in list)
{
callR(item);
}
和另一个 class 到 运行 R 脚本中的方法:
CallR(int item)
{
//init the R engine
REngine.SetEnvironmentVariables();
engine = REngine.GetInstance();
engine.Initialize();
//Perform R
engine.SetSymbol("data", item);
engine.Evaluate("data<-data*data");
//engine.dispose
//Cannot use engine.dispose as re initialization of engine then, is not possible
}
编辑 我还有另外三分之一 class 调用相同的 R 方法。如果我在循环的 class 中实例化它,那么如何在此 class?
中使用该初始化问题: 此代码在本地运行良好,但是在将其部署在服务器上时,它会中断并给出异常:"library stats could not be loaded".
在更深入的搜索中,我发现 this 说是多次初始化 Rengine 导致了这个问题。
因此我的问题是如何在应用程序启动时仅初始化 Rengine 一次,并在像我上面的代码这样的场景中使用它的实例?
您可以修改 CallR class 以拥有 REngine class 的单个实例,并通过仅初始化一次的方法获取它,例如
public static REngine engine = null;
public static REngine GetInitiazedREngine()
{
if (engine==null)
{
REngine.SetEnvironmentVariables();
engine = REngine.GetInstance();
engine.Initialize();
}
return engine;
}
CallR(int item)
{
//Get the initialized R Engine
REngine initializedEngine=GetInitiazedREngine();
//Perform R
initializedEngine.SetSymbol("data", item);
initializedEngine.Evaluate("data<-data*data");
//engine.dispose
//Cannot use engine.dispose as re initialization of engine then, is not possible
}
我认为更好的做法是使用单调模式,如下所示:
public class RNetEngine : IDisposable
{
private bool _disposed;
private REngine _rEngine;
private static readonly object Lock = new object();
private REngine Engine
{
get
{
if (_rEngine == null)
{
lock (Lock)
{
if (_rEngine == null)
{
_rEngine = REngine.GetInstance();
}
}
}
return _rEngine;
}
}
public void Evaluate(string expression)
{
Engine.Evaluate(expression);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (_disposed)
{
return;
}
if (disposing)
{
if (_rEngine != null && !_rEngine.Disposed)
{
_rEngine.Dispose();
}
}
_disposed = true;
}
}
这将使您保持线程安全并在需要时进行处置。我已经将它与 Castle.Windsor 单身人士的生活方式一起使用,所以它不是静态的。