R.NET用于Excel Add-In的多实例(multi-Instance)问题及解决方法(1)

因为要实现多个R实例同时运行的效果,折腾了一个礼拜总算有点结果,虽然没有找到从根本上解决的办法,但也可以暂时保证程序的可用性。希望能把前因后果写清楚,也方便他人借鉴。会分为几篇文章讲,这一篇先记录下R.NET部分。


首先来看看REngine初始化的官方推荐方法:

<span style="font-size:12px;">REngine.SetEnvironmentVariables()
REngine.GetInstance()</span>

就两句,什么参数都不需要设置,第一句还可以省略。其实在早期的R.NET版本中,是可以通过CreateInstance()函数直接创建REngine实例的。但后来这个函数被设置为private,不再支持用户调用,而是在GetInstance()中调用CreateInstance返回REngine实例,并在其中进行了一系列错误排查。


当CreateInstance()还是public的时候,就已经有好多人问过同一个问题:连着调两次应该返回两个实例啊,为啥第二个就挂了呢?(参见)回到源码,这个问题就很好解释了。REngine的基类是DynamicInterop.UnmanagedDll,初始化时,先通过环境变量的路径找到R.dll,再用kernal32函数loadlibrary()加载dll。所以在一个进程(process)里,若dll已经加载,是不能再次加载的。


那么第二个问题来了,既然dll不能同时加载两次,那人为把process分割成几个独立的appdomain可以实现吗?(参见)帖子里JM(R.NET作者)已经明确回答:不可以,一个process只能有一个REngine。我个人觉得,他所谓的不可以主要是他觉得这样的限制是合理的,而且要实现不同AppDomain运行各自的REngine,开发代价很大,没必要去做。


那如果非要实现,该怎么办?

1. 参考这个帖子,里面有详细的讨论。但我没有试他们的方法,觉得还是太麻烦。

2. 用R的Environment模拟多个独立的session。我试过,还是好用的。唯一比较麻烦的就是每次执行代码都要记得带上env参数,否则就跑到GlobalEnv里了。还有对于S4类的method,即使用with()标定环境,还是会定义在GlobalEnv中(原因未知)。若存在同名、不同内容的method,要小心。


我的项目中没有用上面的方法,主要原因是在Excel Add-In调用R.NET,是REngine多实例与Excel的SDI、MDI问题的综合表现,Excel请参见这篇文章。具体详见该系列下篇。


©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值