Laden...

Access "DB" mit async/await auslesen?

Erstellt von Christoph1972 vor 6 Jahren Letzter Beitrag vor 6 Jahren 4.229 Views
Christoph1972 Themenstarter:in
212 Beiträge seit 2008
vor 6 Jahren
Access "DB" mit async/await auslesen?

Hallo zusammen,

ich muss eine Access "Datenbank" mit 2GB (damit ist das Limit bei Access erreicht) auf eine richtige Datenbank migrieren. Die Abfragen auf die Access Datei dauern relativ lange. Nun ist mir die Idee gekommen, die Abfragen mit async und await zu machen, um den Prozess etwas zu beschleunigen. Macht das bei einer Access Datei überhaupt sinn, oder wird der asynchrone Zugriff sowieso geblockt? Oder fliegt mit die Datei nach einer Weile um die Ohren und die neu erzeugte Datenbank ist gleich inkonsistent? 😃

Kann man einen asynchronen Zugriff mit Access realisieren, oder lässt man das besser?

Auf eure Antworten bin ich schon sehr gespannt!

Gruß
Christoph

16.807 Beiträge seit 2008
vor 6 Jahren
  • async/await hat nichts mit Performance im Sinne von mehr Geschwindigkeit zutun.
  • Du willst ist nicht async/await sondern Parallelität

Und ja, Parallelität und Access fliegt Dir um die Ohren.
Ich lege Dir nahe, dass Du Dir mal anschaust, was parallele und was asynchrone Programmierung ist.
Das sind zwei völlig unterschiedliche paar Stiefel aber wird immer wichtiger.

Christoph1972 Themenstarter:in
212 Beiträge seit 2008
vor 6 Jahren

Guten Morgen!

Danke für die Info! Ich hatte ja bereits befürchtet das mir das um die Ohren fliegen könnte. 😃

  • async/await hat nichts mit Performance im Sinne von mehr Geschwindigkeit zutun.
  • Du willst ist nicht async/await sondern Parallelität

Wie meinst du das?

Ich habe das zum Testen so umgesetzt und habe einen erheblichen Zeitvorteil.


private async void Test()
{
    Repository rep = new Repository();

    Stopwatch watch = new Stopwatch();
    watch.Start();

    Task<List<string>> userList = rep.GetUsersAsync(this);
    //var userList = rep.GetUsers();
  
    Task<List<string>> specialUserList = rep.GetSpecialUsersAsync();
    //var specialUserList = rep.GetSpecialUsers();
  
    Task<List<string>> powerUsers = rep.GetPowerUsersAsync();
    //var powerUsers = rep.GetPowerUsers();
 
    ItemsU = await userList;
    ItemsSU = await specialUserList;
    ItemsPU = await powerUsers;

    //ItemsU = userList;
    //ItemsSU = specialUserList;
    //ItemsPU = powerUsers;
    watch.Stop();

    Trace.WriteLine(watch.ElapsedMilliseconds / 1000);
}

Gruß
Christoph

D
985 Beiträge seit 2014
vor 6 Jahren

Asynchron ist nicht Parallel.

Wenn du Wäsche in die Waschmaschine packst, dann brauchst du nicht davor zu warten, bis das Waschprogramm durch ist, denn die kann das alleine. Also asynchron.

Du kannst aber nicht in der gleichen Waschmaschine noch eine Ladung Wäsche waschen lassen. Also nicht parallel (dazu bräuchtest du mehrere Waschmaschinen).

Das was du da machst (asynchrone Aufrufe parallel ausführen) ist nicht immer zulässig.

849 Beiträge seit 2006
vor 6 Jahren

Das was du da machst (asynchrone Aufrufe parallel ausführen) ist nicht immer zulässig.

@Sir Rufo
Kannst Du das einmal ein wenig genauer erläutern? In ähnlicher Form setze ich das auch öfter ein, ein Problem damit konnte ich noch nicht feststellen. Oder spielst Du hier auf die normalen Probleme mit Parallelität an?

H
523 Beiträge seit 2008
vor 6 Jahren

ich muss eine Access "Datenbank" mit 2GB (damit ist das Limit bei Access erreicht) auf eine richtige Datenbank migrieren. !

Auf welche Datenbank möchtest Du Access migrieren? Für verschiedene Datenbanken gibt es fertige Tools, die die Migration übernehmen können (z. B. für den SQL-Server).

16.807 Beiträge seit 2008
vor 6 Jahren

In ähnlicher Form setze ich das auch öfter ein, ein Problem damit konnte ich noch nicht feststellen.

Naja, dann hast Du auch in Deinem ähnlichen Code keinerlei Parallelität. Sagt ja aber nichts aus, dass damit irgendein Problem gelöst oder entsteht.
Es geht nur um die Tatsache, dass await nichts, aber auch gar nichts mit Parallelität zutun hat.

async/await ist - wie der Name schon sagt "asynchron und wartet" - mit dem Unterschied, dass dahinter eine StateMaschine steckt, sodass zB. eine UI nicht blockiert.

Parallel ist hier aber nichts.
MSDN: Tasks are (still) not threads and async is not parallel

Asynchroner Code kann bei gleichzeitiger Parallelität problemlos zu Race Conditions führen - wie alles andere, was Parallel läuft, auch.

301 Beiträge seit 2009
vor 6 Jahren

"Und ja, Parallelität und Access fliegt Dir um die Ohren."

Kann man das noch etwas spezifizieren? IdR fliegt Code ja nirgendwo hin 😃

Wenn ich das richtig verstehe will er die Access Datei auslesen. Von Schreiben war ja nicht die Rede. Das das Schreiben problematisch wird verstehe ich.

Warum ist der reine Lesevorgang ebenfalls gefährlich? Wird die Datei auch bei lesenden Zugriffen gesperrt? Gibt es hier bedenken bzgl. Performanceverlust statt Gewinn?

Wäre super wenn das mal jemand auflisten kann.

16.807 Beiträge seit 2008
vor 6 Jahren

Access ist eine Datenbankdatei.
Parallel-IO auf eine Festplatte trägt seltenst dazu bei, dass der Zugriff schneller wird.

Alle ADO.NET Verbindungstypen unterstützen keine Parallelität - egal ob MSSQL, Oracle-Provider oder Access.
Dazu wäre immer eine zweite Verbindung notwendig.
Anders zB. NoSQL-Engines wie MongoDB, LiteDB, DocumentDB - die alle parallele Zugriffe in einer Connection erlauben; aber auch ACID nicht garantieren müssen.

OleDb wie Access mögen aber i.d.R. überhaupt keine zweite Verbindung.
Führt spätestens beim Write und Lock sehr oft zu kaputten Datenbank-Dateien.
Ich würde bei Access sicherlich nicht meine Hand ins Feuer legen, dass Access safe bei Multi-Connect-Read ist.

849 Beiträge seit 2006
vor 6 Jahren

Sorry für die späte Antwort.. War ein wenig beschäftigt 😃

Naja, dann hast Du auch in Deinem ähnlichen Code keinerlei Parallelität.

Wie kann das dann erklärt werden?:


class Program
    {
        static void Main(string[] args)
        {
            Do();

            Console.WriteLine("Done");
            Console.ReadLine();
        }

        public static async void  Do()
        {
            var task1 = Do1();
            var task2 = Do2();
            var task3 = Do3();

            await task1;
            await task2;
            await task3;

            
        }

        public static async Task Do1()
        {
            await Task.Delay(1000);
            Console.WriteLine($"1 {DateTime.Now:O}");
        }

        public static async Task Do2()
        {
            await Task.Delay(500);
            Console.WriteLine($"2 {DateTime.Now:O}");
        }

        public static async Task Do3()
        {
            await Task.Delay(50);
            Console.WriteLine($"3 {DateTime.Now:O}");
        }
    }


Ausgabe:
Done
3 2018-02-28T06:24:21.4792141+01:00
2 2018-02-28T06:24:21.9261470+01:00
1 2018-02-28T06:24:22.4275398+01:00

Wenns keine parallelität hier gäbe, müsste die Reihenfolge eine andere sein. Natürlich nur wenn die Hauptaufgabe darin besteht auf irgendwas zu warten (I/O). 3 Threads werden hier natürlich nicht gestartet.

4.931 Beiträge seit 2008
vor 6 Jahren

Das ist keine Parallelität, sondern weiterhin nur Asynchronität.

Wenn deine Methoden z.B. alle 2 Konsolenausgaben machen würden:


public static async Task Do1()
{
    await Task.Delay(1000);
    Console.WriteLine("Task1:");
    Console.WriteLine($"1 {DateTime.Now:O}");
}

so würden diese 2 Konsolenausgaben (je asynchroner Methode) auch jeweils direkt hintereinander ausgegeben (selbst wenn du alle Delay-Werte gleich setzt und tausende Läufe durchführst). Im Falle von Parallelität wäre dies nicht mehr gewährleistet und man bräuchte entsprechende Synchronisierungen (z.B. Locking).

16.807 Beiträge seit 2008
vor 6 Jahren

Wenns keine parallelität hier gäbe, müsste die Reihenfolge eine andere sein.

Nein.
Das ist weiterhin nur asynchron aber nicht parallel.
Dein Beispiel ist sehr ungeeignet, um das zu demonstrieren. Du bist einfach drauf reingefallen:
Es gaukelt Dir das einfach vor, weil die Ausführungsreihenfolge einfach nicht garantiert ist. Parallel ist es noch lange nicht.

849 Beiträge seit 2006
vor 6 Jahren

Puh,

ich glaube wir reden hier aneinander vorbei.
Nehmen wir an ich hätte 3 Datenbanken die ich durch einen update befehl aktualisiere der jeweils 3 sekunden dauert (Replace für das Task Delay, also pures i/o).
Würdet ihr also sagen das ich nach dem obigen snippet dann 9 sekunden warte, bis alle fertig sind?

Christoph1972 Themenstarter:in
212 Beiträge seit 2008
vor 6 Jahren

Es gaukelt Dir das einfach vor, weil die Ausführungsreihenfolge einfach nicht garantiert ist. Parallel ist es noch lange nicht.

Was wäre denn jetzt wirklich parallel? Was sollen wir besser machen?

Gruß
Christoph

849 Beiträge seit 2006
vor 6 Jahren

Also um nochmals auf das Beispiel mit der Wäsche zurückzukommen.

Was wir machen ist, eine Maschine anmachen, dann zur nächsten gehen um die anzumachen, dann.... etc.

Das Waschen erfolgt hier imho parallel. Das Probleme mit dieser herangehensweise ist nicht das Waschen selber (Warten auf die Datenbank antwort), sondern das befüllen, entleeren (z.B. Mappen von Objekten) Das machst Du in diesem Fall alleine, also nacheinander.

Das würde sich wiederum nur mit "echter" Parallelität lösen lassen. Sprich mit Parallel.ForEach, Task.StartNew, Task.Run oder wie sie alle heißen.

Deshalb habe ich das Beispiel mit den Delays auch genau so gewählt.

Christoph1972 Themenstarter:in
212 Beiträge seit 2008
vor 6 Jahren

Das Waschen erfolgt hier imho parallel. Das Probleme mit dieser herangehensweise ist nicht das Waschen selber (Warten auf die Datenbank antwort), sondern das befüllen, entleeren (z.B. Mappen von Objekten) Das machst Du in diesem Fall alleine, also nacheinander.

Vielleicht ist es nicht ganz Parallel, aber zum mindest Teil-parallel, vorausgesetzt die Aufgaben sind lang genug. Die Teil-Parallelität ist in dem Link von Abt ja auch dargestellt. Von daher ist es auch nicht korrekt von "keinerlei Parallelität" zu sprechen, oder? Es ist halt nicht Synchron.

Wie dem auch sei, meine eigentliche Frage ist ja schon lange geklärt!

Vielen Dank an euch!

Gruß
Christoph

286 Beiträge seit 2011
vor 6 Jahren

Vielleicht ist es nicht ganz Parallel, aber zum mindest Teil-parallel

Parallel ist ein boolescher Ausdruck. Etwas ist parallel oder es ist nicht parallel. So etwas wie "ein bisschen parallel" gibt es streng genommen nicht.
Was du meinst wäre eine hinreichende Ähnlichkeit zu parallelem Verhalten, aber es ist wie gesagt nicht parallel.

Beste Grüße
emuuu

2+2=5( (für extrem große Werte von 2)

Christoph1972 Themenstarter:in
212 Beiträge seit 2008
vor 6 Jahren

Was du meinst wäre eine hinreichende Ähnlichkeit zu parallelem Verhalten, aber es ist wie gesagt nicht parallel.

Ok, dann sind wir uns ja quasi einig, die Unstimmigkeit ist dann wohl rein rhetorisch.

"hinreichende Ähnlichkeit zu parallelem Verhalten" == "Teil-parallel" 😃

Gruß
Christoph

5.657 Beiträge seit 2006
vor 6 Jahren

Dann würde aber auch gelten:
"hinreichende Ähnlichkeit zu schwangerem Aussehen" == "teil-schwanger"

Teil-Parallelität oder Halb-Parallelität gibt es nicht. Höchstens Teile des Codes, die parallel ausgeführt werden. Oder Code, der nur zum Teil parallel ausgeführt wird. Aber Code, der teil-parallel ausgeführt wird, was sollte das sein...?

Weeks of programming can save you hours of planning

Christoph1972 Themenstarter:in
212 Beiträge seit 2008
vor 6 Jahren

Aber Code, der teil-parallel ausgeführt wird, was sollte das sein...?

Das sollte folgendens sein:

Teile des Codes, die parallel ausgeführt werden. Oder Code, der nur zum Teil parallel ausgeführt wird.

In Meinen Augen ist das nur rhetorisch. Die Ergebnisse sprechen einfach für eine gewisse Parallelität.

EDIT:
Du bezeichnest es ja selbst als Teil-parallel:

Oder Code, der nur zum Teil parallel ausgeführt wird

Gruß
Christoph

5.657 Beiträge seit 2006
vor 6 Jahren

Du würdest also eine Person als teil-schwanger bezeichnen, weil Teile der Bevölkerung schwanger sind. Hier gehts um die richtigen Begrifflichkeiten, das Thema an sich ist längst abgehakt. Und wenn dir mehrere Leute sagen, Teil-Parallelität gibt es nicht, dann beharrst du trotzdem darauf. Dann können wir das so hinnehmen, aber die Diskussion bringt dann halt nix.

Weeks of programming can save you hours of planning

Christoph1972 Themenstarter:in
212 Beiträge seit 2008
vor 6 Jahren

Du würdest also eine Person als teil-schwanger bezeichnen, weil Teile der Bevölkerung schwanger sind. Hier gehts um die richtigen Begrifflichkeiten, das Thema an sich ist längst abgehakt. Und wenn dir mehrere Leute sagen, Teil-Parallelität gibt es nicht, dann beharrst du trotzdem darauf. Dann können wir das so hinnehmen, aber die Diskussion bringt dann halt nix.

Dann erkläre doch bitte wie das Ergebnis ohne Nebenläufigkeiten zustande kommen kann.

Du benutzt doch die selben Begrifflichkeiten -der Code, der nur ** zum Teil parallel** ausgeführt- wie ich, um das zu beschreiben.

Wir können uns auch gerne darüber unterhalten, ob ein Ballon fliegt oder fährt. 😃

Aber wir belassen das jetzt einfach dabei! Ich bin so oder so zufrieden, meine Frage wurde beantwortet.

Gruß
Christoph

T
2.219 Beiträge seit 2008
vor 6 Jahren

@Christoph1972
Ein Beispiel für Asynchron sind Events.
Dieser kannst du mit einem Handler abonnieren.
Diese werden dann von einem anderen Thread ausgeführt, als deinen Hauptthread, dies ist dann aber nicht parallel sondern eben asychron.
Da hier ein anderer Thread als dein Hauptthread die Methode für sich ausführt, aber kein weiterer Thread, wird die Methode nur asynchron verarbeitet.

Parallel wäre es wenn du eine Methode durch X Threads gleichzeitig ausführst.
Ob dies dann mit Tasks, Threads oder der Parallel Klasse gemacht wird, ist dabei unerheblich.
Die Verarbeitung der Methode erfolg parallel.

Deine Vorstellung von Parallel und Asynchron beisst sich hier.
Eine Methode kann asynchron sowie parallel ausgeführt werden, abhängig von der Art des Aufrufs.
Aber nicht beides in einem durch "Teil-Parallel".
Ist der Unterschied klar?

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

5.657 Beiträge seit 2006
vor 6 Jahren

Dann erkläre doch bitte wie das Ergebnis ohne Nebenläufigkeiten zustande kommen kann.

Strg-F: asynchron

Es wurde ja schon mehrfach darauf hingewiesen, daß Parallelität und Asynchronität zwei völlig unterschiedliche Dinge sind. Es gibt ja auch in anderen Lebensbereichen Beispiele, wo zwei völlig unterschiedliche Konzepte einen ähnlichen Effekt hervorrufen können. Wenn du aber gar nicht erst anerkennen möchtest, daß es sich um zwei unterschiedliche Konzepte handelt, dann wirst du auch nicht verstehen, wie sie sich unterscheiden. Und dann hättest du dir die Frage aber auch gleich sparen können...

Weeks of programming can save you hours of planning

Christoph1972 Themenstarter:in
212 Beiträge seit 2008
vor 6 Jahren

Es wurde ja schon mehrfach darauf hingewiesen, daß Parallelität und Asynchronität zwei völlig unterschiedliche Dinge sind.

Ich habe auch nie etwas anderes behauptet. Ich behaupte lediglich, das es eine Nebenläufigkeit geben kann und in meinem Beispiel auch gibt.

Wie würdet ihr denn den Zustand beschreiben den ich in der Skizze (Dateianhang) aufgeführt habe?

Gruß
Christoph

T
2.219 Beiträge seit 2008
vor 6 Jahren

Das ist nicht Asynchron, dass ist parallel.
Den du hast 3 Maschinen, die parallel Wäsche machen.
Ob du dabei die Maschinen gleichzeitig oder nacheinander startest ist unerheblich.
Ist genau das gleich wie 3 Threads zu starten, die die gleiche Verarbeitung parallel durchführen.

Asynchron wäre es, wenn du eine Maschine anwirfst und direkt nach dem starten dein Geschirr spülst ohne auf die Waschmaschine zu warten.
Wenn die Maschine dann fertig ist und sich durch ein entsprechendes Signal bemerkbar macht, kannst du die Wäsche aus der Maschine nehmen.
Diese macht dann eben asynchron von deinen Aktionen ihre Aktion.

Du vermischt hier also wieder parallel und asynchron.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

Christoph1972 Themenstarter:in
212 Beiträge seit 2008
vor 6 Jahren

Das ist nicht Asynchron, dass ist parallel.

Wie, das wurde mir hier die ganze Zeit abgesprochen!? Das sein eben nicht parallel, sogar überhaupt nicht aber gar nicht parallel!

Gruß
Christoph

T
2.219 Beiträge seit 2008
vor 6 Jahren

Du wirfst hier wieder parallel und asynchron in einen Topf, was falsch ist.
Im Link von Abt wird mit async/await das asynchrone Verhalten der Abläufe für E/A und CPU Prozesse erklärt mit async/await erklärt.

Diese laufen aber nicht parallel sondern asynchron, da der UI-Thread weiterlaufen kann während der asynchrone Prozess weiterläuft bis er fertig ist.

Du musst das umbedingt lernen zu trennen, sonst drehen wir uns hier nur im Kreis.
Klar braucht man für asynchrone Abläufe einen eigenen Thread/Task, der eben asynchon von deinem Hauptthread arbeitet.
Er läuft parallel zu deinem Thread aber arbeitet eben asynchon von diesem seinen Code ab.

Parallel und asynchron sind immer noch zwei paar Schuhe.
Dein eigenes Beispiel oben ist auch nur asynchron, da 3 Tasks jeweils unterschiedliche aber nicht gleiche Verarbeitungen durchführen.
Diese laufen, falls diese auf eigene Threads durch Task.Factory geforkt werden, vielleicht parallel aber die führen dabei auch asynchrone Verarbeitungen aus.

Um das noch etwas zu vereinfachen.

Asynchron: Task A läuft durch Methode A, Task B läuft durch Methode B, UI-Thread durchläuft Event Code o.ä.
Parallel: X Tasks durchlaufen die gleiche Verarbeitung

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

16.807 Beiträge seit 2008
vor 6 Jahren

Ich behaupte lediglich, das es eine Nebenläufigkeit geben kann und in meinem Beispiel auch gibt.

Nein.

Christoph1972 Themenstarter:in
212 Beiträge seit 2008
vor 6 Jahren

@T-Virus: Vielen Dank für die nette Erläuterung!

Also rufe ich Asynchrone Methoden parallel auf, oder?

Gruß
Christoph