Asynchrones Verhalten mit async

  • C#
  • .NET (FX) 4.5–4.8

Es gibt 8 Antworten in diesem Thema. Der letzte Beitrag () ist von Trade.

    Asynchrones Verhalten mit async

    Das Programm, an dem ich arbeite liest Daten aus einer Datei, verarbeitet diese und gibt sie aus. (WPF Tabellen/Diagramme)
    Am Anfang hab ich nicht damit gerechnet, dass die Datenmengen so groß werden und somit alles synchron programmiert.

    Jetzt dauert es aber an manchen Stellen sehr lange und der User weiß nicht was los ist. (Ein Ladebalken o.ä. wäre hier sinnvoll)
    Also muss ich das ganze eventbasiert oder asynchron machen.

    Normalerweise würde ich in meiner Klasse, die die Daten an meine UI weitergibt ein Event einbauen, was dann ausgelöst wird, wenn die Daten fertig geladen worden sind.
    Nun gibt es aber ja die neuen Schlüsselwörter async und await, die ich in dem Sinne mal probieren wollte.

    Allerdings weiß ich hier nicht genau wie ich die einsetzten muss.
    Muss ich die wirklich nur an meine Methoden anbringen, die die Verbindung zwischen UI und Daten darstellen, oder muss ich das durch das ganze Programm durchziehen (also z.B auch beim Lesen der Daten aus den Dateien) ?
    Bin mir da gerade irgendwie etwas unsicher, und wollte deshalb hier kurz nachhören.
    Ja, und? :D
    Mir ist nicht ganz klar, wo's nun hakt. :P Also ​async - await ist sicherlich eine gute Lösung für sowas. Mit ​IProgress<T> kannst Du auch ohne Weiteres den Fortschritt übermitteln und anzeigen.

    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
    Achso. ^^

    ​async müssen die sein, die Du auch awaiten willst. Das kommt stark drauf an, wie das aussieht. Hast Du generell eine Methode, die synchron ist, aber asynchron (awaitable) sein soll, musst Du diese ​async machen und den Inhalt in einen ​Task wrappen.

    C#-Quellcode

    1. ​public void DoIt()
    2. {
    3. for (int i = 0; i <= 1000; ++i)
    4. {
    5. Console.WriteLine(i.ToString());
    6. }
    7. }
    8. public async Task DoItAsync()
    9. {
    10. return await Task.Run(() => DoIt());
    11. }
    12. public async void Test()
    13. {
    14. Console.WriteLine("Counting to 1000:");
    15. await DoItAsync();
    16. }


    Normal würde das obere ja blockieren, weil's komplett synchron ist. Unten wrappst Du das allerdings in einen Task, der dann asynchron läuft und nicht mehr blockiert.
    Wenn Du in einer async-Methode einen Aufruf awaitest, dann musst Du das nicht machen und es läuft automatisch nicht mehr synchron.

    Es wäre wohl gut, einen Code zu haben, damit man das speziell erklären könnte. ;)

    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
    Was du probieren könntest ist folgendes: Lagere das aus-der-Datei-lesen in eine Funktion aus, welche ein Task<T> liefert (T ist in dem Fall der Generische Bezeichner für eine Klasse, welche deine gelesenen Daten repräsentiert)
    dann "awaitest" du im GUI Thread einfach das Ergebnis der Funktion.

    Nachteil hier: Eine Progressbar ist leider nicht so einfach zu realisieren, wie mit der Progress<T> Variante

    Lg Radinator
    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell

    Trade schrieb:

    die Du auch awaiten willst


    Das stimmt nicht. Eine Methode muss nur als async markiert werden wenn du innerhalb dieser Methode await verwenden willst.
    await selbst kann man auf alles anwenden was ein Task ist.

    Statt

    C#-Quellcode

    1. public async Task DoItAsync()
    2. {
    3. return await Task.Run(() => DoIt());
    4. }


    würde schon das reichen(was übrigens auch weniger overhead bringt da hier keine unnötige state machine generiert wird)

    C#-Quellcode

    1. public Task DoItAsync()
    2. {
    3. return Task.Run(() => DoIt());
    4. }
    @Pinki Danke Dir. Dann war ich da tatsächlich ziemlich falsch informiert und dachte, dass man es explizit als ​async markieren muss, um es awaiten zu können.

    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!: