0

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

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 方法的第三类。如果我在创建循环的类中实例化它,那么如何在这个类中使用该初始化?

问题:此代码在本地运行良好,但是在服务器上部署它时,它会中断并给出异常:“无法加载库统计信息”。

在深入搜索时,我发现表明多次初始化 Rengine 会导致此问题。

因此我的问题是如何在应用程序启动时只初始化一次 Rengine 并在我上面的代码这样的场景中使用它的实例?

4

2 回答 2

2

我认为更好的做法是使用 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;
  }
}

这将使您保持线程安全并在需要时进行处理。我已经将它与 Castle.Windsor Singleton 生活方式一起使用,所以它不是静态的。

于 2016-10-13T08:54:57.577 回答
1

您可以将 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 
}

于 2016-10-10T12:36:17.977 回答