2017-01-03 2 views
1

Ich verwende C#, .Net 4.6.x und die Telerik-Steuerelemente für WinForms in Visual Studio 2017 RC. Die Anwendung besteht aus einem "Haupt" -Fenster, das einen RadRibbon und ein RadPageView verwendet. Das RadPageView wird dynamisch mit Seiten gefüllt, die auf einem Suchformular basieren, das die erste Seite ist, oder von einem Benutzer, der ein neues leeres Formular anfordert. Die anderen Seiten werden von RadPageViewPage geerbt und haben eine zusätzliche Eigenschaft namens "TQC". TQC verweist auf ein benutzerdefiniertes Steuerelement, das auf der Seite geladen wird.Der beste Weg, OutOfMemoryException zu lösen? (C#)

Das TQC verfügt über mehrere Dropdown-Listen und Textbereiche in RadPageViewPages, die alle in einem RadPageView-Steuerelement innerhalb des TQC-Objekts enthalten sind. Es bindet keine Daten an seine Steuerelemente, bis das RPVP (die Klasse, die RadPageViewPage erbt) ausgewählt ist. Eine der Dropdownlisten enthält etwa 200 Einträge, wenn sie ausgefüllt sind (eine Liste von Konten).

Das Problem, das ich habe, ist, dass, wenn die äußere RadPageView Remove() s eine Seite, der Speicher von dieser Seite nicht freigegeben wird, in der Größenordnung von ein paar hundert Megabyte. Dies ist problematisch, da die Zielrechner zwischen 4 GB und 8 GB RAM haben. Ich habe versucht, die Datenobjekte, die die Steuerelemente auffüllen, als Teil des schließenden Ereignisses auf null zu setzen, aber nichts hat sich geändert. Ich habe auch versucht explizit die Methode Dispose() auf alle Nachkommen des RadPageViewPage Aufruf wie folgt:

private void rpvQtabs_PageRemoved(object sender, RadPageViewEventArgs e) 
    { 

     foreach (TQC c in e.Page.Controls) 
     {     
      foreach (Control ca in c.Controls) 
      { 
       foreach (Control cac in ca.Controls) 
       { 
        cac.Dispose(); 
       } 
       ca.Dispose(); 
      } 
      c.Dispose(); 
     } 
     e.Page.Dispose();   
    } 

Ich bin immer noch einen verrückten großen Speicherverlust bekommen, und wenn mehr als 5 Registerkarten durch den Benutzer betrachtet werden (auch Wenn sie die Seite schließen), folgt in Kürze eine OutOfMemoryException. Ich habe versucht, den Performance Profiler anzubringen, aber es stürzt bei dem Versuch ab. VS 2015 ist im Moment keine Option. Wie kann ich sicherstellen, dass die Seiten ordnungsgemäß entsorgt werden, oder den Speicherbedarf der extrem großen Dropdown-Listen reduzieren? Dies ist unser erster Ausflug in Telerik.

Als Antwort auf Fragen in den Kommentaren:

Das Objekt, das den Fehler wirft, ist in der Regel relativ zufällig und hängt davon ab, welche Konten belastet werden. Es ist nichts unendlich rekursives. Dies ist, wie die Kontrolle des ursprünglich geladen (eine spezielle Verbindungsklasse verwendet wird):

public static List<Account> List(bool includeDefaults = true) 
    { 
     //search 
     var rs = new List<Account>(); 
     string q = "select distinct r.ID, r.name from db.addressbook r"; 
     DataTable dt = new DataTable(); 
     using (var cmd = new CustomConnectionClass()) 
     { 
      cmd.Safety.Off(); 
      dt = cmd.ExecuteDirectQuery(q); 
     } 

     foreach (DataRow r in dt.Rows) 
     { 
      var a = new Account(); 
      a.ID = long.Parse(r[0].ToString()); 
      a.Name = r[1].ToString(); 
      rs.Add(a); 
     } 
     rs = rs.OrderBy(t => t.ID).ToList(); 
     var n = new Account(); 
     n.ID = 0; 
     n.Name = "Generic Account"; 
     var o = new Account(); 
     o.ID = 999999; 
     o.Name = n.Name; 
     rs.InsertRange(0, new Account[] { n, o }); 
     return rs; 

    } 
+0

Wie viele Artikel hast du in DropDownList? Was ist der Gegenstand? Ein komplexes Objekt oder nur ein ID + Wert? –

+0

Es ist an ein IEnumerable gebunden. Es enthält 16 Eigenschaften, von denen die meisten nur beim Erstellen der Liste nicht geladen werden. Die einzigen zwei, die tatsächlich ausgefüllt werden, sind die ID-Nummer und der Name, die verkettet werden, um den Anzeigetext im Dropdown über die ToString() -Methode darzustellen. IEnumerable wird tatsächlich erstellt, wenn die Anwendung als Teil des Hauptformulars geladen wird, auf die jedoch von untergeordneten Objekten zugegriffen wird, um sie an diese Steuerelemente zu binden. – CDove

+0

Ich habe nur eine DropDownList mit 100000 Zeile Datatable ohne irgendein Problem laden. Datatable enthält 9 Spalten alle gesetzt. Also 200Entry * 16 Eigenschaften sollten kein Problem sein. –

Antwort

0

Nach einer weiteren Untersuchung konnte ich klären, dass dies beinhaltet, wie Telerik seine Themen und Kontrollen lädt. Wenn Sie alle Datenquellen für die Dropdownlisten static verwenden, wurde der Footprint etwas reduziert, aber der Themenmanager und die Themen für die Steuerelemente in den einzelnen Registerkarten wurden jedes Mal neu geladen. Konstruktionsbedingt sind sie nicht notwendigerweise angeordnet, wenn die Steuerung geschlossen und angeordnet ist. Das Design der Benutzeroberfläche muss überarbeitet werden, um zu verhindern, dass Benutzer nicht genügend Arbeitsspeicher haben. Das Problem verschwindet, wenn das gleiche Design mit Standard-WinForms erstellt wird.

+0

Sie sollten einen Bericht Fehler zu telerik darüber machen. Sie können einen schönen Rabatt auf Ihre nächste Lizenz erhalten. –

Verwandte Themen