我最近一直在尝试使用R.NET让R与.NET和C#交谈.到目前为止一直进展顺利,但我遇到了一些我似乎无法解决的问题.
我对简单的基本命令没有任何问题.我制作了一个简单的计算器,以及将数据导入数据网格的东西.但现在我不断收到以下错误:
在"R.NET!RDotNet.Internals.blah3 :: Invoke"类型的垃圾收集委托上进行了回调.这可能会导致应用程序崩溃,损坏和数据丢失.将委托传递给非托管代码时,托管应用程序必须将它们保持活动状态,直到确保它们永远不会被调用.
它开始于我尝试重复导入文本文件,只是为了测试一些东西.我以各种方式查找了这个错误 - 在浏览页面几个小时后,似乎有很多这种错误的原因.随着时间的推移,我一直在将代码剥离到越来越简单的任务,试图消除可能性.我现在有这个:
public Form1()
{
InitializeComponent();
REngine.SetDllDirectory(@"C:\Program Files\R\R-2.13.0\bin\i386");
REngine.CreateInstance("RDotNet");
using (REngine currentEngine = REngine.GetInstanceFromID("RDotNet"))
{
for (int i = 0; i < 1000; ++i)
{
currentEngine.EagerEvaluate("test <- " + i.ToString());
NumericVector returned = currentEngine.GetSymbol("test").AsNumeric();
textBox1.Text += returned[0];
}
}
}
Run Code Online (Sandbox Code Playgroud)
它只是增加textBox1.Text中的计数.我一直在做这个测试,按下按钮增加值,但这让我的手指在一段时间后疼痛!它通常可以在抛出上述错误之前管理负载.
起初这个代码似乎很好 - 所以我假设我一直在做的其他事情是某种原因导致的问题,以及上面引用的错误的原因.所以这就是我放入for循环的原因.循环可以在几百次运行中没有问题地运行,但随后错误开始.
现在,我确实读过垃圾收集器可以调用这种错误来摆脱我一直在使用的实例.我已经尝试过各种各样的建议,我最了解它们.这些包括使用GC.KeepAlive()(没有运气),还在一个单独的类中创建一个无法摆脱的私有字段.可悲的是,这也没有用.
还有什么我可以尝试的吗?我对C#非常非常新,所以我很感激任何有关如何使其工作的指示.我非常假设我所建议的方法缺乏成功与(1)我自己在实现标准修复中的错误(这似乎很可能)或者(2)与R.NET相关的怪癖不明白.
任何帮助将不胜感激!
看起来像R.NET中的一个错误.您看到的异常发生在.NET层将回调传递给非托管代码但随后让代理收集垃圾时.我发现你的repro代码中没有代理用法,因此结论是它必须在R.NET中.