Недавно я пытался использовать R.NET, чтобы заставить R разговаривать с .NET и С#. Пока все идет хорошо, но я попал в ловушку, которую я, похоже, не могу решить.
У меня не было проблем с простыми базовыми командами. Я сделал простой калькулятор и что-то импортировать данные в сетку данных. Но теперь я продолжаю получать следующую ошибку:
Обратный вызов был сделан на сборщике мусора типа "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];
}
}
}
Все, что он делает, - это увеличение счетчика в textBox1.Text. Я делал это как тест с нажатием кнопки, увеличивая значение, но через некоторое время это заставляло меня болеть пальцем! Обычно он может управлять нагрузками прессов, прежде чем выбросить ошибку выше.
Сначала этот код казался прекрасным - поэтому я предположил, что другой материал, который я делал, был чем-то причиной проблемы, а также причиной приведенной выше ошибки. Поэтому я поставил цикл for. Цикл может работать без проблем на несколько сотен прогонов, но затем появляется ошибка.
Теперь я прочитал, что этот вид ошибки может быть вызван сборщиком мусора, избавляющимся от экземпляра, с которым я работал. Я пробовал разные предложения, которые я читал, насколько я их понимаю. Они включали использование GC.KeepAlive() (без везения), а также создание частного поля в отдельном классе, от которого нельзя избавиться. К сожалению, это тоже не сработало.
Есть ли что-нибудь еще, что я могу попробовать? Я очень, очень новичок в С#, поэтому я был бы признателен за любые указания о том, как это сделать. Я очень полагаю, что мой недостаток в успехе с предложенными методами либо связан с (1) моими собственными ошибками в реализации стандартных исправлений (это кажется наиболее вероятным), либо (2) причудой, связанной с R.NET, что я Понятно.
Любая помощь будет принята с благодарностью!