2011-06-26 23 views
16

私は最近、.NETとC#に話しRを取得するためにR.NETを使用してしようとしてきたためにガベージコレクションを停止します。これまでのところはうまくいっていますが、私は解決できないように見えます。管理対象外の委任

私は、単純な、基本的なコマンドでは問題がなかったしました。私は単純な電卓を作って、データをデータグリッドにインポートするものを作った。しかし、今私は次のエラーを取得し続ける:

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]; 

       } 

      } 

     } 

これはテキストボックス1のテキストの数を増やしています。値を増やすボタン・プレスでテストしていましたが、しばらくしてから指が痛かったのです!上記のエラーを投げる前に、一般にプレスの負荷を管理することができます。

最初に、このコードは大丈夫に見えた - ので、私は私がやっていた他のものを想定していたが何とか問題の原因だけでなく、上記の引用されたエラーの原因でした。だからこそ私はforループを作りました。ループは数百回の実行で問題なく実行できますが、エラーが発生します。

ここで、この種のエラーはガベージコレクタによって呼び出され、私が動作していたインスタンスを取り除くことができますと。私は、私が理解しているように、私が読んだ様々な提案を試みました。これらにはGC.KeepAlive()(運がない)を使用することと、取り除かれない別のクラスにプライベートフィールドを作成することが含まれています。残念ながら、これはどちらもうまくいきませんでした。

は、私は試すことができます何かありますか?私は非常に、非常にC#の新しいので、私はどのようにこの作業を得るためのポインターに感謝したい。私は、提案された方法の成功の欠如が、(1)自分自身の標準的な修正を実装する間違い(これはおそらくそう思われる)または(2)R.NETに関連した不思議なこと理解していない。

ご協力いただければ幸いです!

+2

*正確に*あなたはGC.KeepAliveの呼び出しを入れたのはどこ?これは正しい修正ですが、最後に必要なものでなければなりません。メソッドの終了は最も簡単です。 –

+1

私はあなたの特定の問題については考えていませんが、私は最近、テキストファイルに繰り返し書き込もうとしたときと同様の状況を思い出させます。それは、OSが次の書き込み操作が行われる前にファイル接続を閉じることを完了していない散発的な場合を除いて、ほとんどの場合に機能しました。私はあなたがあなたのファイルから読んでいるだけだと知っていますが、レッスンはおそらくまだ成り立っています:ファイル操作の数を最小限に抑えるような方法でコードを書いてみてください。言い換えれば、ファイルを読み込んで、ループを終了するまでメモリに格納します。 – Andrie

+1

アンマネージドコードに代理人を渡すことはありません。コードのその部分を追加できますか? –

答えて

7

はR.NETのバグのように見えます。表示されている例外は、.NETレイヤーがアンマネージコードにコールバックを渡した後に、代理人にガベージコレクションをさせるときに発生します。私はあなたのreproコードで代理人の使用を見ないので、それはR.NETになければならないという結論になります。

+0

偉大な、スティーブン - 感謝!あなたは正しいです、私は実現することなくそうしていたかどうかはわかりませんでしたが、私はどんな種類の代議員も呼びませんでした。 C#の新機能で、私がエラーを起こしたかどうかはわかりませんでした。私はちょうど見つけたR.NETのフォーラムにこれを掲示し、うまくいけば修正ができます。乾杯! – hayward

2

Stephenが示唆していたように、私が使っていたR.NETのバグであり、私がやっていたことに間違いではないことが判明しました(これは私の元々の推測でした。 !)。 R.NETの作者はR.NETフォーラムの投稿に返信していますが、幸いにもこの問題を解決してR.NETを更新しましたが、dllの形式ではありません(ソースファイルをインポートするのは簡単ですしかし)。

私は、ソースファイルの最新バージョンは、実際にはこの問題に悩まされないことを確認することができます。ハレイ!ここに答えた人に感謝します。残念ながら、私は長い間、単純なバグに頭を悩ましていましたが、解決策を探している間にC#/ .NETの詳細を知ることができました。

関連する問題