Performanceproblem mit CollectionViews

  • WPF MVVM
  • .NET (FX) 4.5–4.8

Es gibt 7 Antworten in diesem Thema. Der letzte Beitrag () ist von DTF.

    Performanceproblem mit CollectionViews

    Hey,

    ich hab ein Problem mit der Performance in folgender Sub:

    VB.NET-Quellcode

    1. Public Sub SucheZuruecksetzen_Execute(obj As Object)
    2. Mouse.OverrideCursor = System.Windows.Input.Cursors.Wait
    3. TextFilter = ""
    4. BPMMin = 0
    5. If MainModule.InhaltGesamt.Count > 0 Then
    6. BPMMax = MainModule.InhaltGesamt.Max(Function(x) x.BPM)
    7. Else
    8. BPMMax = 999
    9. End If
    10. For Each item In AnzuzeigendeGenres
    11. item.IstSelektiert = True
    12. Next
    13. Mouse.OverrideCursor = System.Windows.Input.Cursors.Arrow
    14. 'RefreshView()
    15. End Sub


    Diese Codestellen stehen damit in Verbindung:

    VB.NET-Quellcode

    1. Public Property TextFilter() As String
    2. Get
    3. If _TextFilter IsNot Nothing Then
    4. Return _TextFilter.ToLower
    5. End If
    6. End Get
    7. Set(ByVal value As String)
    8. Mouse.OverrideCursor = System.Windows.Input.Cursors.AppStarting
    9. _TextFilter = value.ToLower
    10. RaisePropertyChanged()
    11. If value.Length >= 3 Then RefreshView()
    12. Mouse.OverrideCursor = System.Windows.Input.Cursors.Arrow
    13. Debug.WriteLine("")
    14. End Set
    15. End Property



    VB.NET-Quellcode

    1. Public Sub RefreshView()
    2. AnzuzeigendeInterpreten.Refresh()
    3. AnzuzeigendeAlben.Refresh()
    4. AnzuzeigendeMusiktitel.Refresh()
    5. AnzuzeigendeRadiostreams.Refresh()
    6. Debug.WriteLine("Event RefreshView gefeuert!!")
    7. End Sub


    In meinem Fall hat die ObservableColletion InhaltGesamt um die 5500 Items.
    AnzuzeigendeInterpreten, -Alben, -Musiktitel, -Radiostreams sind vom Typ ICollectionView und werden in jeweils einer Listbox angezeigt.

    Also InhaltGesamt hat für jeden Eintrag eine Audiodatei, die dann auf die vier ICollectionViews sortiert werden:

    VB.NET-Quellcode

    1. Public Sub ErstelleDefault()
    2. _AnzuzeigendeInterpreten = CollectionViewSource.GetDefaultView(MainModule.InhaltGesamt.OrderBy(Function(o) o.Interpret).GroupBy(Function(f) f.Interpret).Select(Function(g) g.First()))
    3. _AnzuzeigendeAlben = CollectionViewSource.GetDefaultView(MainModule.InhaltGesamt.OrderBy(Function(o) o.Album).GroupBy(Function(f) f.Album).Select(Function(g) g.First()))
    4. _AnzuzeigendeMusiktitel = CollectionViewSource.GetDefaultView(MainModule.InhaltGesamt.OrderBy(Function(o) o.Musiktitel).GroupBy(Function(f) f.Dateiname).Select(Function(g) g.First()))
    5. _AnzuzeigendeRadiostreams = CollectionViewSource.GetDefaultView(MainModule.InhaltGesamt.OrderBy(Function(o) o.Album).GroupBy(Function(f) f.Album).Select(Function(g) g.First()))
    6. _AnzuzeigendeInterpreten.Filter = AddressOf AnzuzeigendeInterpreten_Filter
    7. _AnzuzeigendeAlben.Filter = AddressOf AnzuzeigendeAlben_Filter
    8. _AnzuzeigendeMusiktitel.Filter = AddressOf AnzuzeigendeMusiktitel_Filter
    9. _AnzuzeigendeRadiostreams.Filter = AddressOf AnzuzeigendeRadiostreams_Filter
    10. _AnzuzeigendeInterpreten.SortDescriptions.Add(New SortDescription(NameOf(ViewModel.MP3FileInfoVM.Interpret), ListSortDirection.Ascending))
    11. _AnzuzeigendeAlben.SortDescriptions.Add(New SortDescription(NameOf(ViewModel.MP3FileInfoVM.Album), ListSortDirection.Ascending))
    12. _AnzuzeigendeMusiktitel.SortDescriptions.Add(New SortDescription(NameOf(ViewModel.MP3FileInfoVM.Musiktitel), ListSortDirection.Ascending))
    13. _AnzuzeigendeRadiostreams.SortDescriptions.Add(New SortDescription(NameOf(ViewModel.MP3FileInfoVM.Album), ListSortDirection.Ascending))
    14. Testkommando = New RelayCommand(AddressOf TestkommandoAusführen)
    15. MarkierterInterpret = -1
    16. MarkiertesAlbum = -1
    17. MarkierterMusiktitel = -1
    18. MarkierterRadiostream = -1
    19. End Sub

    VB.NET-Quellcode



    Wenn ich die Suche nun zurücksetze, dann dauert es eine Ewigkeit, bis die Sub abgearbeitet ist, bzw. das Programm hängt sogar fest.

    Hat jemand eine Idee, wie ich das performanter gestalten kann?
    Bitte Titel präzisieren.

    An welcher Stelle hängt es genau? Einfach mal ein paar Haltepunkte verteilen und messen. Wird ja in VS angezeigt, wie lange es von einem Haltepunkt zum nächsten braucht.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    VaporiZed schrieb:

    Bitte Titel präzisieren.


    Oh das hatte ich komplett übersehen :)

    VaporiZed schrieb:

    An welcher Stelle hängt es genau? Einfach mal ein paar Haltepunkte verteilen und messen. Wird ja in VS angezeigt, wie lange es von einem Haltepunkt zum nächsten braucht.



    Okay ich schau mal was ich tun kann...
    Mal Datetime.now verwenden um den Startzeitpunkt zwischenzuspeichern, dann eine TimeSpan (DateTime.now - starttime), schon weist du wie lange es von a nach b dauert. Aber ich denke deine Datensammelart, mit gruppierung und sortierung dauert so lange. Könnte also dein Datenmanagement sein. Ich hab alle radio-browser.info sender (30k+), alle laden dauert keine 300ms, UI ist beim filtern ratzfatz fertig, keine 150ms, habs nicht gemessen aber geht so schnell, da brauch ich nicht messen.

    Schick mir mal eine bereinigte Projektmappe, dann schau ich mir mal deine Architektur an.
    Zitat von mir 2023:
    Was interessiert mich Rechtschreibung? Der Compiler wird meckern wenn nötig :D
    Hab es so gemacht wie @VaporiZed es beschrieben hat: Haltepunkt rein, dann mit F11 Einzelschritte gemacht, und auf die verstrichenen Millisekunden geguckt, und schon hatte ich den Übeltäter:

    Wenn ich die Eigenschaft IstSelektiert von AnzuzeigendeGenress setze, dann wird für jede dieser Änderungen ein EventHandler ausgeführt, also hab ich den für diese For-Schleife einfach temporär wieder removed...

    @DTF
    Wie tust du deine RadioBrowser-Daten specichern? Als JSON serialiseren und dann in eine Textdatei oder hast du eine "echte" Datenbank?
    Weil das dauert bei mir auch ne halbe Ewigkeit. Aber kein Wunder, bei 5500 Datensätzen mit jeweils 18 Eigenschaften, die meisten davon sind Strings...

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „kafffee“ ()

    Ich hab das mit Dependency-Injection gemacht. Zur Laufzeit lade ich DLLs aus einem bestimmten Ordner(Plugins), da sind Klassen drin die bestimmte Interfaces implementieren, sogar einzelne Tabs vom TabControl hab ich ein Interface für, so kann sich jeder seine eigenen Tabs mit Playlisten, Datenansichten, eigenen Datenbank-Zugriff usw. machen, auch Im und Export Plugins.

    Aktuell hab ich das mit SQLite im Hintergrund. Bin soweit glücklich mit der Performence, nur bei einem ListView mit vielen Bildern kann das Filtern mal 2-3 Sekunden dauern, da finde ich sicher auch noch was.
    Zitat von mir 2023:
    Was interessiert mich Rechtschreibung? Der Compiler wird meckern wenn nötig :D

    kafffee schrieb:

    Ah okay das heisst dein User kann sich sein UI selbst zusammenstellen?


    Genau das. In so einer DLL dann ein View, ein ViewModel, ein Interface dann kann das geladen werden. DLL in einen bestimmten Ordner und das wars.
    Zitat von mir 2023:
    Was interessiert mich Rechtschreibung? Der Compiler wird meckern wenn nötig :D