yo Leute,
ich hatte eben ein interessantes Problem mit Async und Await. Kurz zum Programm: Es wird ein Ordner ausgewählt wo Logdateien gespeichert sind. Alles zusammen hat dieser Ordner rund 250 Dateien welche insgesamt ~ 500MB an Daten beinhalten.
Diese muss ich alle Zeile für Zeile einlesen um etwas zu überprüfen.
Der Code sieht abgespeckt folgendermaßen aus:
Spoiler anzeigen
Die Mainform abonniert das ProgressChanged Event:
So wie der Code jetzt dasteht wird alles korrekt gelesen, die Form ist NICHT blockiert und des InfoLabel gibt den geänderten Text korrekt aus:
Wenn ich aber aus der Methode ReadFiles() das
Mich würde eben interessieren warum ich dieses zusätzliche Task.Run hier noch benötige, da die Methode ja ansich schon als async deklariert wurde.
Vielleicht hat wer eine Idee dazu.
lg
ich hatte eben ein interessantes Problem mit Async und Await. Kurz zum Programm: Es wird ein Ordner ausgewählt wo Logdateien gespeichert sind. Alles zusammen hat dieser Ordner rund 250 Dateien welche insgesamt ~ 500MB an Daten beinhalten.
Diese muss ich alle Zeile für Zeile einlesen um etwas zu überprüfen.
Der Code sieht abgespeckt folgendermaßen aus:
C#-Quellcode
- public List<StoreInfo> StoreInfos { get; set; }
- public DirectoryInfo Directory { get; set; }
- public string SearchPattern { get; set; }
- public Progress<string> Progress { get; set; }
- public decimal HourStart { get; set; }
- public decimal HourEnd { get; set; }
- public async Task ReadFiles()
- {
- this.StoreInfos = new List<StoreInfo>();
- await Task.Run( async () =>
- {
- foreach(var file in Directory.GetFiles(SearchPattern))
- {
- var storeInfo = new StoreInfo();
- storeInfo.StoreId = int.Parse(Regex.Match(file.Name, @"\d+").Value);
- ((IProgress<string>)Progress).Report(string.Format("Datei '{0}' wird gelesen", file.Name));
- var errors = await ReadAllLinesAsync(file.FullName, Encoding.Default);
- storeInfo.ProgramOnlyStartCount = errors;
- var existingEntry = StoreInfos.FirstOrDefault((s) => s.StoreId == storeInfo.StoreId);
- if(existingEntry == null)
- StoreInfos.Add(storeInfo);
- else
- existingEntry.ProgramOnlyStartCount += storeInfo.ProgramOnlyStartCount;
- }
- });
- ((IProgress<string>)Progress).Report("Alle Dateien wurden gelesen!");
- }
- private async Task<int> ReadAllLinesAsync(string filepath, Encoding encoding)
- {
- var lastLine = string.Empty;
- var startCount = 0;
- using(var reader = new StreamReader(filepath, encoding))
- {
- string line;
- while((line = await reader.ReadLineAsync()) != null)
- {
- int hour = 0;
- if(line.Contains(_startText) && int.TryParse(line.Substring(9, 2), out hour) && hour >= HourStart && hour <= HourEnd)
- {
- if(lastLine != string.Empty && !lastLine.Contains(_endText))
- startCount++;
- }
- lastLine = line;
- }
- }
- return startCount;
- }
Die Mainform abonniert das ProgressChanged Event:
So wie der Code jetzt dasteht wird alles korrekt gelesen, die Form ist NICHT blockiert und des InfoLabel gibt den geänderten Text korrekt aus:
Wenn ich aber aus der Methode ReadFiles() das
await Task.Run( async () =>
entferne, werden die paar ersten Files im InfoLabel noch angezeigt und dann hängt die Form komplett. Das heißt, dass ich nichts mehr auf der Form klicken kann. Nicht einmal das X. Es steht auch nicht "Keine Rückmeldung", wie man es überlichweise kennt in der Titelleiste. Man kann einfach nicht interagieren mit der Form bis der Leseprozess beendet ist.Mich würde eben interessieren warum ich dieses zusätzliche Task.Run hier noch benötige, da die Methode ja ansich schon als async deklariert wurde.
Vielleicht hat wer eine Idee dazu.
lg
ScheduleLib 0.0.1.0
Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten
Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten