Frage

Ich habe einige Probleme wurden mit mit LINQ-to-SQL um Speichernutzung. Ich verwende es in einem Windows-Dienst einige Verarbeitung zu tun, und ich bin durch eine große Menge an Daten, Looping, dass ich wieder aus dem Kontext zu ziehen. Ja - ich weiß, dass ich dies mit einer gespeicherten Prozedur tun könnte, aber es gibt Gründe, warum das eine weniger als ideale Lösung wäre,

.

Wie auch immer, was ich sehe, ist im Grunde genommen ist der Speicher nicht einmal freigegeben werden, nachdem ich context.SubmitChanges() nennen. So beende ich alle möglichen seltsamen Dinge mit bis zu machen wie nur zurückziehen 100 Datensätze zum Zeitpunkt oder mehrere Kontexte erstellen und sie alle tun getrennte Aufgaben. Wenn ich die gleiche DataContext halten und verwenden Sie es später für andere Anrufe, es isst nur mehr und mehr Speicher. Auch wenn ich Clear() auf der „var tableRows“ Array rufen, dass die Abfrage zu mir zurückkommt, setzen Sie ihn auf Null zu bringen, und rufen SYstem.GC.Collect() -. Es immer noch nicht auf den Speicher entbindet

Jetzt habe ich gelesen einige darüber, wie Sie DataContexts schnell verwenden sollten und schnell entsorgen, aber es scheint, wie ihr sollte ein Weg, um den Kontext zu zwingen, alle seine Daten-Dump (oder alle seine Tracking-Daten für einen bestimmten Tabelle) zu einem bestimmten Zeitpunkt zu gewährleisten, der Speicher frei ist.

Wer weiß, welche Schritte garantieren, dass der Speicher freigegeben wird?

War es hilfreich?

Lösung

Wenn Sie nicht brauchen, Objektverfolgung Satz DataContext.ObjectTrackingEnabled false . Wenn Sie es tun, dann können Sie Reflexion rufen Sie das DataContext.ClearCache () verwenden, obwohl Sie, dass interne seit ihrer bewusst sein müssen, ist es Thema in einer zukünftigen Version des Frameworks verschwinden. Und soweit ich das beurteilen kann, das Framework selbst es nicht verwenden, aber es nicht löscht Sie die Objekt-Cache.

Andere Tipps

Ein Datacontext verfolgt alle Objekte, die es jemals geholt. Es wird dies nicht loslassen, bis es Müll gesammelt ist. Auch, wie es IDisposable implementiert, müssen Sie Dispose anrufen oder die using Anweisung verwenden.

Das ist der richtige Weg zu gehen:

using(DataContext myDC = new DataContext)
{
  //  Do stuff
} //DataContext is disposed

Als David out Punkte, sollten Sie von der Datacontext verfügen unter Verwendung eines Block verwendet wird.

Es scheint, dass das primäre Anliegen über das Erstellen und eine Reihe von Datacontext Objekten zu entsorgen. Dies ist, wie linq2sql ausgelegt ist. Die Datacontext soll kurze Lebensdauer haben. Da Sie eine Menge Daten aus der DB ziehen, macht es Sinn, dass es eine Menge von Speichernutzung sein. Sie sind auf dem richtigen Weg, indem Sie Ihre Daten in Blöcken zu verarbeiten.

Haben Sie keine Angst, eine Tonne von Datacontexts zu schaffen. Sie sind so konzipiert, dass die Art und Weise verwendet werden.

Danke Jungs - ich werde die Clearcache-Methode überprüfen. Nur zur Klarstellung (für zukünftige Leser), die Situation, in der ich die Erinnerung usuage immer so etwas wie das war:

using(DataContext context = new DataContext())
{
   while(true)
   {
      int skipAmount = 0;
      var rows = context.tables.Select(x => x.Dept == "Dept").Skip(skipAmount).Take(100);

      //break out of loop when out of rows

      foreach(table t in rows)
      {
         //make changes to t   
      }

      context.SubmitChanges();
      skipAmount += rows.Count();

      rows.Clear();
      rows = null;

      //at this point, even though the rows have been cleared and changes have been
      //submitted, the context is still holding onto a reference somewhere to the
      //removed rows.  So unless you create a new context, memory usuage keeps on growing
   }
}

Ich lief in ein ähnliches Problem. In meinem Fall half die Eigenschaften von DataContext.ObjectTrackingEnabled auf false zu etablieren. Aber es funktioniert nur im Fall von durch die Reihen laufen wie folgt:

using (var db = new DataContext())
{
    db.ObjectTrackingEnabled = false;
    var documents = from d in db.GetTable<T>()
                     select d;
    foreach (var doc in documents)
    {
        ...
    }
}

Wenn zum Beispiel in der Abfrage die Methoden ToArray () zu verwenden oder ToList () - keine Wirkung

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top