Laden...

Asyncrones laden einer ObservableColl. und syncron. mit DataGrid

Erstellt von echdeneth vor 2 Jahren Letzter Beitrag vor 2 Jahren 285 Views
echdeneth Themenstarter:in
161 Beiträge seit 2019
vor 2 Jahren
Asyncrones laden einer ObservableColl. und syncron. mit DataGrid

Moin,

ich versuche in MVVM eine ObservableCollection (OC) asyncron zu laden und die Daten in einer DataGrid anzeigen zu lassen.

Basis ist folgende:


private SQL MySQL = new SQL();
public ObservableCollection<Model> OC { get; set; }
...
OC = new ObservableCollection<Model>(MySQL.GetSomeStuff()); //

Und eine Datagrid, irgendwelcher Daten harrend...

Also habe ich versucht für ein besseres Verständnis und um hinter die Mechanik von await/async/etc. zu kommen und zu Verstehen, fertige Lösungen zu testen und analysieren.
WPF-Performancetipp Teil 2: „ObservableCollection“ synchronisieren


BindingOperations.EnableCollectionSynchronization(OC, _listLock);
Task.Run(() => LoadData());

private async void LoadData() // Fehlermeldung: In dieser Async-Methode fehlen die "await"-Operatoren, weshalb sie synchron ausgeführt wird.
        {
            OC = new ObservableCollection<Model>(MySQL.GetSomeStuff());
        }

hat nicht funktioniert... OC.Count = 0

Eine andere Vorgehensweise war:


            App.Current.Dispatcher.BeginInvoke((Action)delegate ()
            {
                OC = new ObservableCollection<Model>(MySQL.GetSomeStuff());
            });

OC.Count = 300+, aber DataGrid Leer...

XAML:


    <Window.DataContext>
        <vm:MainViewModel />
    </Window.DataContext>
...
                    <DataGrid 
                              AutoGenerateColumns="False"
                              ItemsSource="{Binding OC, IsAsync=True}"
                              SelectedItem="{Binding SelectedRow}"
                              CanUserAddRows="False"
                              IsReadOnly="True"
                              RowDetailsVisibilityMode="{Binding RowDetailsVisibilityMode}"
                              materialDesign:DataGridAssist.CellPadding="8,12,8,12"
                              Margin="0,0,0,12" Grid.Row="1" 
                              SelectionMode="{Binding SelectionMode}"
                              SelectionUnit="FullRow">
                              ...
                  </DataGrid>

Ich habe leider keine Ahnung was ich falsch mache...

"Man muß die Dinge so einfach wie möglich machen. Aber nicht einfacher." Albert Einstein

G
16 Beiträge seit 2019
vor 2 Jahren

auch wenn das Video schon ein bisschen älter ist, gibt es doch einen sehr guten Einblick

Fluid User Interfaces with async/await - BastaConfernce

Er zeigt auch sehr viel im Code selbst und ist somit gut verständlich.

16.807 Beiträge seit 2008
vor 2 Jahren

Meiner Ansicht nach lässt sich sowas viel einfacher und übersichtlicher mit Reactive Extensions und eine Subscription lösen.
Zudem sieht mir


private SQL MySQL = new SQL();

nicht gerade nach einer guten Umsetzung aus, wenn das ein Repository darstellen soll (wonach es aussieht).
Riecht stark nach Service Locator Pattern, der ein Anti Pattern darstellt.

Fehlermeldung: In dieser Async-Methode fehlen die "await"-Operatoren, weshalb sie synchron ausgeführt wird.

Jo, dann mach erst mal Deine Implementierung sauber über async/await, was die Basis ist.
Ohne das machts wenig Sinn.

Asynchrone Programmierung mit async und await

async void ist übrigens auch ein Pitfall, den man nur in ganz bestimmten Situationen verwenden darf (hier nicht!)
Async/Await – Bewährte Verfahren bei der asynchronen Programmierung

echdeneth Themenstarter:in
161 Beiträge seit 2019
vor 2 Jahren

... sieht mir

  
private SQL MySQL = new SQL();  
  

nicht gerade nach einer guten Umsetzung aus...

Ja, Sorry, gefällt mir auch nicht besonders, ich weiss (noch) nicht wie ich es anders machen soll.
(Darüber sollen die Enumerables der SQL Anfragen zurückgegeben werden)

Jo, dann mach erst mal Deine Implementierung sauber über async/await, was die Basis ist.
Ohne das machts wenig Sinn...

Jo, also zurück auf die Schulbank...
(kleine Ausrede: async und co waren in der Ausbildung nicht enthalten...)

"Man muß die Dinge so einfach wie möglich machen. Aber nicht einfacher." Albert Einstein

16.807 Beiträge seit 2008
vor 2 Jahren

Darüber sollen die Enumerables der SQL Anfragen zurückgegeben werden

Was aber falsch wäre, weil ein Repository entweder ein materialisiertes Ergebnis zurück geben sollte (und damit Array oder List etc) oder IQueryable.
Intermediate materialization (C#)

Ja, Sorry, gefällt mir auch nicht besonders, ich weiss (noch) nicht wie ich es anders machen soll.

Der Repository Pattern ist sehr gut dokumentiert und über viele Sprachen hinweg ein Alltagsthema, schon Dokus angeschaut?
Implementieren von Repository-und Arbeitseinheiten Mustern in einer ASP.NET MVC-Anwendung (9 von 10)
(Man sollte den Hinweis im Artikel beachten, wieso der Sample Code in diesem alten Artikel noch IEnumerable verwendet)

Jo, also zurück auf die Schulbank...

Definitiv. Asynchrone Programmierung ist ein Konzept, das man verstehen muss.
Mit try and error kommt man bei konzeptionellen Themen erfahrungsgemäß leider nicht wirklich auf einen grünen Zweig.
Wirst sehr wahrscheinlich auf die Nase fliegen und in viele Pitfalls rennen - das kostet Dich ja nur unnötig Zeit und macht Frust.

async und co waren in der Ausbildung nicht enthalten

Würde mich auch wundern, weil eine Schule i.d.R. nur Grundlagen beibringen kann, wozu ich mal async/await als Implementierung eines asynchronen Konzepts nicht zählen würde.