我最近一直在嘗試使用R.NET來讓R與.NET和C#交談。到目前爲止它一直很順利,但我遇到了一個我似乎無法解決的障礙。爲非託管代表停止垃圾回收
我對簡單的基本命令沒有任何問題。我做了一個簡單的計算器,並將數據導入數據網格。但現在我不斷收到以下錯誤:
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.
它開始時,我試圖重複導入文本文件,只是爲了測試一些東西。我以各種方式查找了這個錯誤 - 在幾個小時的頁面拖網之後,似乎有這種類型錯誤的原因。隨着時間的推移,我一直在剝離我的代碼,以執行越來越多的簡單任務以消除可能性。我現在有這個:
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()(沒有運氣),還創建一個私人領域在一個單獨的類,不能擺脫。可悲的是,這也沒有奏效。
還有什麼我可以嘗試嗎?我對C#非常非常陌生,所以我很感激任何關於如何讓它工作的指針。我非常認爲,我所提出的方法缺乏成功或者與(1)我自己在實現標準修復方面的錯誤(這似乎很可能)或(2)與我無關的R.NET相關的怪癖不明白。
任何幫助將不勝感激!
確實*您是否把GC.KeepAlive呼叫?這是正確的解決方法,但它必須在最後一次需要之後 - 方法結束最簡單。 –
我不知道你的具體問題,但它讓我想起了最近我曾經反覆嘗試寫入文本文件的類似情況。它大部分時間都在工作,除了在我的下一次寫入操作發生之前操作系統尚未完成關閉文件連接的零星情況之外。我知道你只是從你的文件中讀取數據,但是這個課程可能仍然存在:嘗試以這種方式編寫代碼,以儘量減少文件操作的數量。換句話說,讀取文件並將其存儲在內存中,直到完成循環。 – Andrie
我看不到您將委託傳遞給非託管代碼。你可以添加你的代碼的一部分? –