I've recently been trying out using R.NET to get R talking to .NET and C#. It's been going very well so far, but I've hit a snag that I don't seem to be able to solve.
I've had no issues with simple, basic commands. I made a simple calculator, and something to import data into a data grid. But now I keep getting the following error:
A callback was made on a garbage collected delegate of type 'R.NET!RDotNet.Internals.blah3::Invoke'. This may cause application crashes,
corruption and data loss. When passing delegates to unmanaged code, they must
be kept alive by the managed application until it is guaranteed that they will never be called.
It began when I tried to repeatedly import a text file, just to test something. I've looked up this error in various ways - after hours of trawling through pages, it seems that there are a number of causes of this type of error. As time has gone on, I've been stripping back my code to more and more simple tasks to try to eliminate possibilities. I've got this now:
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;
All it does is increment a count in textBox1.Text. I had been doing it as a test with a button press incrementing the value, but this was making my finger ache after a while! It could typically manage loads of presses before throwing the error above.
At first this code seemed to be fine - so I had assumed the other stuff I had been doing was somehow the cause of the problem, as well as the cause of the error quoted above. So that's why I put in the for loop. The loop can run with no problems for several hundred runs, but then the error kicks in.
Now, I did read that this kind of error can be called by the garbage collector getting rid of the instance I've been working with. I've tried various suggestions that I read, as best I understand them. These have included using GC.KeepAlive() (no luck), and also creating a private field in a separate class that can't be gotten rid of. Sadly this didn't work either.
Is there anything else that I can try? I'm very, very new to C# so I'd appreciate any pointers on how to get this working. I assume very much that my lack of success with the methods suggested are either something to do with (1) my own mistakes in implementing the standard fixes (this seems most likely) or (2) a quirk associated with R.NET that I haven't understood.
Any help would be greatly appreciated!
Looks like a bug in R.NET. The exception you're seeing happens when a .NET layer passes a callback to unmanaged code but then lets the delegate get garbage collected. I see no delegate usage in your repro code, hence the conclusion that it must be in R.NET.