如何在c# .net中全局初始化引擎

本文关键字:全局 初始化 引擎 net | 更新日期: 2023-09-27 18:12:24

我在c#项目中使用R.Net和R.Net. community包来启用R脚本。我有一个c#类如下:

foreach(var item in list)
{
  callR(item);
}

和另一个类中的方法来运行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 
}

编辑我还有第三个类,它调用相同的R方法。如果我在创建循环的类中实例化它,那么如何在这个类中使用这个初始化呢?

:这段代码在本地工作得很好,但是在服务器上部署时,它会中断并给出异常:"library stats could not be loaded"。

在深入搜索时,我发现这说明多次初始化引擎会导致此问题。

因此,我的问题是如何初始化引擎在应用程序启动本身只有一次,并使用其实例的场景,如我的代码上面?

如何在c# .net中全局初始化引擎

我认为更好的做法是使用Singletone模式,就像这样:

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;
  }
}

这将保证你的线程安全,并在需要时进行处理。我和卡塞尔用过这个。温莎的单身生活方式,所以不是一成不变的。

您可以修改CallR类,使其具有一个单独的REngine类实例,并通过只初始化一次的方法获得它,例如

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 
}