2017-01-16 3 views
0

Ich habe ein kleines Programm in C#, das die R.Net-Bibliothek lädt, um einige Berechnungen auszulagern, die ich in C# nicht ausführen kann, nämlich die Twitter-Anomalie-Erkennungsbibliothek. Wenn der Code das Konsolenfenster beendet, wird es leider nicht mehr ausgeführt. Wenn ich es in debug ausführen, scheint die Codeausführung fehlerfrei zu sein, also vermute ich, dass es etwas mit der Bereinigung der REngine zu tun hat, da ich (schließlich) einen Fehler wie in diesem Bild bekomme.Probleme beim Beenden des C# -Programms, das R.Net verwendet

Error message thrown by VS Community 2015, Update 3

Nach dem ich eine andere bekommen von VS Pop-up besagt, „Debuggen wird deaktiviert, aber noch nicht abgeschlossen ist, entweder es erzwingen, indem Sie durch Drücken dieser Taste zu stoppen oder fortzusetzen, warten“.

-Code ist etwa wie folgt:

class SHESD_Test 
{ 
    private static REngine engine; 

    internal SHESD_Test(IEnumerable<Double> d) 
    { 
     try 
     { 
      if(engine==null) 
      { 
       engine = REngine.GetInstance(); 
       engine.Initialize(); 
       engine.Evaluate("library(AnomalyDetection)"); //Loads Twitter library 
      } 
      var dInR = engine.CreateNumericVector(d.toArray()); 
      engine.SetSymbol("data", dInR); 
      var outVar = engine.Evaluate("outVar <- AnomalyDetectionVec(data, max_anoms=0.02, direction='both', plot=FALSE, period=96)"); 
      /* Some other stuff that grabs data out of outVar in R and stores in member variables */ 

     } 
     catch (Exception e) 
     { /* Log error */ } 
    } 
    //Called from elsewhere once everything is complete, but behaviour is the same if I don't call it 
    internal static void cleanup()   
    { 
     engine.ForceGarbageCollection(); 
     engine.Dispose(); 
     engine == null; 
    } 
} 

den Fehlercode googeln, es sieht aus wie ein Timeout abgelaufen ist, aber für das Leben von mir, ich kann nicht herausfinden, warum.

Der Code selbst funktioniert gut, es ist nur in den Ausgang von main(), und nicht das Bit, wo die REngine außerhalb des Geltungsbereichs fällt, also vielleicht in der Müllsammlung Dinge schief gehen?

+1

Werfen Sie einfach das da draußen; 'REngine' implementiert eindeutig' IDisposable'. Das ganze Problem kann verschwinden, wenn Sie statt einer 'static' Klassenvariable einen' using' Block verwenden. – CDove

+0

Ich habe es so gemacht, wie ich diese Klasse mehrfach erstelle. Vielleicht sollte ich die REngine in der aufrufenden Klasse mit einem "using" erstellen und über den Konstruktor einreichen - wird es einen Wirbel geben – JetSetJim

+1

Wenn du 'using' in' SHESD_Test' steckst, wird es die Instanz erstellen, run all Funktionen darauf, und dann entsorgen Sie es jedes Mal, wenn SHESD_Test aufgerufen wird. Es sei denn, es ist ein Speicher Schwein, das ist wahrscheinlich der Weg zu gehen, und Sie müssen nicht für "if (engine == null)" – CDove

Antwort

0

Darüber hinaus liegt die Ursache in der Bibliotheksfunktion, die ein Plot-Fenster im Rückgabewert erzeugt, selbst wenn es nicht gesagt wird. Deren Code ist:

# Lastly, return anoms and optionally the plot if requested by the user 
if(plot){ 
    return (list(anoms = anoms, plot = xgraph)) 
} else { 
    return (list(anoms = anoms, ***plot = plot.new()***)) # <-Looky here! 
} 

zu meinem Code die folgende Zeile, wenn ich mit dem Motor fertig bin:

engine.Evaluate("graphics.off()"); 

schließt das seltsam leeres Fenster, die nicht in der Lage sein scheint zu sein, geschlossen durch entweder die ForceGarbageCollection- oder die Dispose-Methode - wodurch es wahrscheinlich bleibt, dass es darauf ankommt, auf etwas zu warten, das niemals passieren wird, und somit dieses Zeitüberschreitungsausnahmefenster auszulösen.

Verwandte Themen