none
async und await Problem RRS feed

  • Frage

  • Bin letztens durch die neue Programmierung mit Windows Phone 8.1 das erste mal auf die asynchronen Methoden bzw. async und await aufmerksam geworden da ich ja auch verstehen will was ich programmiere habe ich mich mal darüber schlau gemacht und musste feststellen das die ganze Sache doch nicht so einfach wie gedacht ist. 

    Ich habe den folgenden Code so modifiziert (auch mit Hilfe aus dem Forum) das ich Text in eine Datei Speichern kann(Hierbei streiche ich jetzt mal alles unwichtige aus dem Code wenn jedoch hier der Fehler nicht liegt werde ich den kompletten hinein stellen):

    //Diese Methode wirt beim öffnen meiner Seite aufgerufen
    
    public async void age_Loaded(object sender, RoutedEventArgs e)
    {
          new readandwrite().write("Mathe}Eng}", 0);
          string read = await new readandwrite().read(0);
          if (read != "")
          {
          }
    {
    
    //Die nächsten beiden Methoden befinden sich in der Klasse readandwrite und sind wie die Methoden Namen sagen zum lesen und schreiben einer txt. Datei gedacht 
    
    public async Task<string> read(int area)
    {
         string[] array;
                 
         var folder = ApplicationData.Current.LocalFolder;
         var getfile = await folder.GetFileAsync("sp.txt");
         var readedtext = await FileIO.ReadTextAsync(getfile);
         array = readedtext.Split('~');
    
         return array[area];
    }
    
    
    public async void write(string content, int area)
    {
         
               var folder =                          
               ApplicationData.Current.LocalFolder;
               string write;
               string[] array;
               var getfile = await folder.GetFileAsync("sp.txt");
               var readedtext = await FileIO.ReadTextAsync(getfile);//Datei lesen
               array = readedtext.Split('~');
               var creatfile = await folder.CreateFileAsync("sp.txt", CreationCollisionOption.ReplaceExisting);
               write = null;
                     for (int i = 0; i < 7; i++)
                     {
                         if (i != area)
                         {
                             write += array[i] + "~";
                         }
                         else
                         {
                             write += content + "~";
                         }
    
                     }
                     await FileIO.WriteTextAsync(creatfile, write);
    }

    Mein Problem ist das wenn ich die Seite öffne die variable read manchmal leer und manchmal wie bei der ersten Zeile befohlen Mathe}Eng} ist. 

    Wenn ich nochmal den Code genauer erläutern soll schreibt es bitte, jedoch denke ich das alles ganz durchsichtig ist.

    Danke schon einmal im Voraus!

    Samstag, 3. Januar 2015 21:19

Antworten

  • Hallo,

    ergänzend zu Thomas Hinweisen fällt mir noch folgendes auf:

    • Du liest und schreibst die Datei bei jedem Zugriff. Cache sie doch lieber. Das heißt, das du das Array gleich in der Klasse behältst und somit immer darauf zugreifen kannst. So sparst du dir das ständige lesen- und schreiben, welches sehr Leistungsaufwendig ist.
    • Weiterhin solltest du beim schreiben lieber einen StringBuilder oder gleich einen Stream einsetzen um alles in die Datei zu schreiben. Das verbinden per +-Operator erzeugt jedes mal einen neuen String, was auch wieder sehr langsam ist.
    • Du schreibst bei jedem Schreibvorgang ein ~ ans Ende. Beim einlesen erhältst du damit jedes mal ein weiteres, leeres Element am Ende des Arrays.
    • Außerdem solltest du die Instanz von ReadAndWrite in age_Loaded aufbewahren und nicht jedes mal neu erzeugen. Dafür wäre ggf. eine statische Klasse besser geeignet.

    Zu dem Fehlverhalten selbst:

    Ich vermute mal, das irgendwo ein Fehler auftritt und die Methode einfach abgebrochen wird. So wäre es beispielsweise möglich, das die Datei gar nicht existiert (hat Thomas ja schon geschrieben) oder das die Datei keine 7 durch ~ getrennten Einträge hat und somit beim Schreiben ein Fehler auftritt.
    Weiterhin musst du natürlich sicher stellen, das du auch die Zugriffsrechte auf den Ordner hast. Sonst bekommst du eine AccessDeniedException.
    Sollte eine Exception auftreten und der Code einfach fort geführt werden (hängt von den Debug-Einstellungen ab) erscheint trotzdem eine Fehlermeldung im Aufgabefenster von VS.

    Wichtig wäre ggf. wirklich BreakPoints zu setzen um zu überprüfen was in den Variablen steht etc. Auch schrittweises Debuggen (F11) kann helfen, da du hier siehst wann die Ausführung abgebrochen wird.


    Tom Lambert - C# MVP
    Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
    Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
    Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets

    • Als Antwort markiert martinrath Sonntag, 4. Januar 2015 13:49
    Samstag, 3. Januar 2015 22:20
  • Hallo Martin,

    schau Dir mal an: Deceptive simplicity of async and await

    denn Deine Write Methode fällt auch über das dort beschriebene Problem.

    Gruß Elmar

    • Als Antwort markiert martinrath Sonntag, 4. Januar 2015 13:49
    Sonntag, 4. Januar 2015 09:01

Alle Antworten

  • Hallo,

    ich hoffe du kannst ausschließen, dass es an der Datei liegt, dass diese zum Zeitpunkt des Lesens also IMMER vorhanden ist.

    Dann eine Kleinigkeit noch zum Code-Stil: Man schreibt Klassennamen immer Groß, alos z.B. "ReadAndWrite" und Methoden-Namen eben so ("Read()", "Weite()")

    Der Code schaut eigentlich ganz richtig in meinen Augen aus, wobei ich es nur sehr seltsam finde, dass du den Anfang des Textes immer neu reinschreibst. Oder ist das nur zu Testzwecken?

    Und du musst nicht die Datei neu erstellen, denn du kannst die IStorageFile-Instanz einfach wiederverwenden.

    Weitere Informationen gibt es im MSDN: Windows Runtime Apps

    Und was ich dir empfehlen würde, mache einfach mal eine Breakpoint nachdem die Datei gelesen wurde und schau dir mit dem Debugger an, ob die Werte richtig gelesen wurden und die Fehler am restlichen Code liegen oder nicht.


    © 2015 Thomas Roskop


    Samstag, 3. Januar 2015 21:33
  • Oke, danke für die Korrektur.

    Also normalerweise liegt sie immer vor denn ich greife nur über die Methoden read und write auf die Datei zu und das habe ich oben geschrieben, wenn du jetzt praktisch ausschließen kannst das ich sie mit den Methoden löschen(oder sonst was) würde, müsste alles passen.

    Samstag, 3. Januar 2015 21:42
  • Bei Datei erstellen meinst du wohl die Zeile, oder?

      var creatfile = await folder.CreateFileAsync("sp.txt", CreationCollisionOption.ReplaceExisting);
    und das ich immer am Anfang das selbe in den Code schreibe ist wie du gesagt hast nur zum testen da.


    • Bearbeitet martinrath Samstag, 3. Januar 2015 21:56
    Samstag, 3. Januar 2015 21:53
  • Hallo,

    ergänzend zu Thomas Hinweisen fällt mir noch folgendes auf:

    • Du liest und schreibst die Datei bei jedem Zugriff. Cache sie doch lieber. Das heißt, das du das Array gleich in der Klasse behältst und somit immer darauf zugreifen kannst. So sparst du dir das ständige lesen- und schreiben, welches sehr Leistungsaufwendig ist.
    • Weiterhin solltest du beim schreiben lieber einen StringBuilder oder gleich einen Stream einsetzen um alles in die Datei zu schreiben. Das verbinden per +-Operator erzeugt jedes mal einen neuen String, was auch wieder sehr langsam ist.
    • Du schreibst bei jedem Schreibvorgang ein ~ ans Ende. Beim einlesen erhältst du damit jedes mal ein weiteres, leeres Element am Ende des Arrays.
    • Außerdem solltest du die Instanz von ReadAndWrite in age_Loaded aufbewahren und nicht jedes mal neu erzeugen. Dafür wäre ggf. eine statische Klasse besser geeignet.

    Zu dem Fehlverhalten selbst:

    Ich vermute mal, das irgendwo ein Fehler auftritt und die Methode einfach abgebrochen wird. So wäre es beispielsweise möglich, das die Datei gar nicht existiert (hat Thomas ja schon geschrieben) oder das die Datei keine 7 durch ~ getrennten Einträge hat und somit beim Schreiben ein Fehler auftritt.
    Weiterhin musst du natürlich sicher stellen, das du auch die Zugriffsrechte auf den Ordner hast. Sonst bekommst du eine AccessDeniedException.
    Sollte eine Exception auftreten und der Code einfach fort geführt werden (hängt von den Debug-Einstellungen ab) erscheint trotzdem eine Fehlermeldung im Aufgabefenster von VS.

    Wichtig wäre ggf. wirklich BreakPoints zu setzen um zu überprüfen was in den Variablen steht etc. Auch schrittweises Debuggen (F11) kann helfen, da du hier siehst wann die Ausführung abgebrochen wird.


    Tom Lambert - C# MVP
    Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
    Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
    Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets

    • Als Antwort markiert martinrath Sonntag, 4. Januar 2015 13:49
    Samstag, 3. Januar 2015 22:20
  • Ich werde mich morgen sofort an die arbeit machen, ich setzte mal die ganzen Breakpoints und werde vorerst mal alle relevanten Verbesserungsvorschläge umsetzen. Morgen teil ich euch dann mit wie weit ich gekommen bin.
    Samstag, 3. Januar 2015 22:42
  • Hallo Martin,

    schau Dir mal an: Deceptive simplicity of async and await

    denn Deine Write Methode fällt auch über das dort beschriebene Problem.

    Gruß Elmar

    • Als Antwort markiert martinrath Sonntag, 4. Januar 2015 13:49
    Sonntag, 4. Januar 2015 09:01
  • Ich hoffe das es jeder noch sieht den es interessiert denn ich glaube jetzt den Fehler gefunden zu haben(zumindest funktioniert bis jetzt alles.

    Ich habe alles so gemacht wie in den Beitrag von Elmar beschrieben:

    - Habe die Methoden Bezeichnung geändert:

    async public Task Write(string content, int area)
    {
    }

    - und habe den Methoden Aufruf geändert:

    readandwrite rw = new readandwrite(); 
    await rw.Write("Mathe}Eng}", 0);


    • Als Antwort markiert martinrath Sonntag, 4. Januar 2015 13:49
    • Tag als Antwort aufgehoben martinrath Sonntag, 4. Januar 2015 13:49
    Sonntag, 4. Januar 2015 13:48
  • Danke hat mir sehr geholfen die genaue Lösung von meinem Problem habe ich oben als Antwort nochmal hin gepostet. 
    Sonntag, 4. Januar 2015 13:49