Benutzer mit den meisten Antworten
Datei innerhalb einer bestimmten Zeit einlesen, welche Möglichkeiten stehen zur Verfügung

Frage
-
Hi,
ich muss nach einem Button Klick, eine Textdatei xy einlesen.
Sollte diese Datei innerhalb 1000ms nicht vorhanden sein, müßte ich eine Fehlermeldung ausgeben.
Wie könnte ich das Ziel erreichen?
Anwendung sollte natürlich nicht stehen bleiben.
Müßte ich da schon einen eigenen Thread erstellen.
Ich suche Ansatzmöglichkeiten, wie man so etwas typisch löst.
Threads, über das async task await oder über Filewatcher.Vielleicht kann jemand die Möglichkeiten andeuten. Es muss eigentlich dann doch synchron, weil ich einen Fehler ausgeben muss, anderseits wieder nicht, weil die Anwendung nicht hängen darf.
Danke im Voraus.
Gruß, Markus
Antworten
-
Hallo Markus,
ja, das blockiert die GUI nicht und du kannst an der markierten Stelle weiter machen.
private async void btn_Click(object sender, EventArgs e) { try { var data = await ReadDataAsync("\\datei.pdf", 1000); // hier irgendwas mit der Datei anstellen string info = DateiVerarbeiten(data); } catch ( FileNotFoundException ) { } catch ( Exception ) { } } private string DateiVerarbeiten(byte[] pData) { int len = pData?.Length ?? throw new ArgumentNullException(); return $"Die Datei ist {len} Bytes groß."; }
Vielleicht interessieren dich auch diese Hinweise...
Gruß
- Bearbeitet K. Pater Samstag, 16. Dezember 2017 13:48
- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Administrator Freitag, 29. Dezember 2017 07:18
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Administrator Freitag, 5. Januar 2018 14:00
Alle Antworten
-
Hi Markus,
um die Oberfläche bedienbar zu halten, ist der Ladevorgang in einen separaten Thread auszulagern. Dort kannst Du das Leden wieder asynchron starten und in diesem Thread mit Time-Out auf das Ende des Ladevorgangs warten. Entweder das Warten wird mit Time-Out oder mit dem Ende des Einlesens beendet, wen vor dem Time-Out das Lade-Ende erreicht wird.--
Viele Grüsse
Peter Fleischer (ehem. MVP)
Meine Homepage mit Tipps und Tricks -
Hallo Markus,
vielleicht hilft ergänzend noch dieses Beispiel weiter:
// Button-Click-Handler private async void btn_Click(object sender, EventArgs e) { try { var data = await ReadDataAsync("\\datei.pdf", 1000); } catch ( FileNotFoundException ) { } catch ( Exception ) { } } // Daten async einlesen... private async Task<byte[]> ReadDataAsync(string pDatei, int pTimeOutMs) { int n = 0; int m = (int)Math.Ceiling(pTimeOutMs / 100.0); while ( !File.Exists(pDatei) ) { await Task.Delay(100); n++; if ( n == m ) { throw new FileNotFoundException(); } } FileInfo fi = new FileInfo(pDatei); byte[] data = new byte[fi.Length]; using ( var fs = fi.OpenRead() ) { int gelesen = await fs.ReadAsync(data, 0, data.Length); return data; } }
Falls die Datei nicht in der angegebenen Zeit gefunden wurde, kannst du das in im Catch-FileNotFound-Abschnitt behandeln.
Gruß
-
Hi Peter,ich habe es über einen BackgroundThread gelöst.
Was auffällt, ich kann es nicht debuggen, müsste ich da in der Entwicklungsumgebung
was einstellen. Wenn ja, was und wo?
Die Quelle f gibt es nicht.Falls Du noch eine andere Lösung in petto hast, sehr gerne, dann kann ich vergleichen.
@K. Pater, ich denke Deine Lösung ist besser.
private async void btn_Click(object sender, EventArgs e) { try { var data = await ReadDataAsync("\\datei.pdf", 1000); } catch ( FileNotFoundException ) { } catch ( Exception ) { } }
Da wird dann auch gewartet und ich kann es behandeln, wie synchron, sehe ich korrekt?Gruß, Markus
Quelle für "f:\dd\NDP\fx\src\compmod\system\componentmodel\BackgroundWorker.cs" wird gesucht. (No checksum.)
Die Datei "f:\dd\NDP\fx\src\compmod\system\componentmodel\BackgroundWorker.cs" ist nicht vorhanden.
"f:\dd\NDP\fx\src\compmod\system\componentmodel\BackgroundWorker.cs" wird in Skriptdokumenten gesucht...
"f:\dd\NDP\fx\src\compmod\system\componentmodel\BackgroundWorker.cs" wird in Projekten gesucht.Quelle für "f:\dd\ndp\clr\src\BCL\system\string.cs" wird gesucht. (No checksum.)
Die Datei "f:\dd\ndp\clr\src\BCL\system\string.cs" ist nicht vorhanden.
"f:\dd\ndp\clr\src\BCL\system\string.cs" wird in Skriptdokumenten gesucht...
"f:\dd\ndp\clr\src\BCL\system\string.cs" wird in Projekten gesucht.public class ImportProgram : BackgroundWorker { // in parameters public string Path; public string Filename; public string Extension; public int TimoutForReadTheFile; // out parameters public bool FileExist; public ImportProgram(RunWorkerCompletedEventHandler completed) { FileExist = false; this.DoWork += new DoWorkEventHandler(ThreadProc); this.RunWorkerCompleted += completed; this.WorkerSupportsCancellation = true; } // .... private void ThreadProc(object sender, DoWorkEventArgs e) { DateTime dateTime = DateTime.Now.ToLocalTime(); ImportProgram bw = (ImportProgram)sender; System.Diagnostics.Debug.Assert(this == bw); e.Cancel = bw.CancellationPending; if (!Directory.Exists(bw.Path)) { Trace.WriteLine($"The path '{bw.Path}' is not exist"); return; } Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); FileExist = false; do { //FileInfo[] files = di.GetFiles(pattern, SearchOption.AllDirectories); //var filteredFiles = files.Where(x => x.CreationTime > dateTimePicker1.Value //foreach (var file in filteredFiles) if (!File.Exists(bw.Path + bw.Filename + bw.Extension)) { Trace.WriteLine($"The file '{bw.Path + bw.Filename + bw.Extension}' is not exist, was not created"); Thread.Sleep(100); } else { FileExist = true; break; } } while (stopWatch.ElapsedMilliseconds < TimoutForReadTheFile); } }
-
Hallo Markus,
ja, das blockiert die GUI nicht und du kannst an der markierten Stelle weiter machen.
private async void btn_Click(object sender, EventArgs e) { try { var data = await ReadDataAsync("\\datei.pdf", 1000); // hier irgendwas mit der Datei anstellen string info = DateiVerarbeiten(data); } catch ( FileNotFoundException ) { } catch ( Exception ) { } } private string DateiVerarbeiten(byte[] pData) { int len = pData?.Length ?? throw new ArgumentNullException(); return $"Die Datei ist {len} Bytes groß."; }
Vielleicht interessieren dich auch diese Hinweise...
Gruß
- Bearbeitet K. Pater Samstag, 16. Dezember 2017 13:48
- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Administrator Freitag, 29. Dezember 2017 07:18
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Administrator Freitag, 5. Januar 2018 14:00
-
private async void btn_Click(object sender, EventArgs e) { try { var data = await ReadDataAsync("\\datei.pdf", 1000); // hier irgendwas mit der Datei anstellen string info = DateiVerarbeiten(data); } catch ( FileNotFoundException ) { } catch ( Exception ) { } } private string DateiVerarbeiten(byte[] pData) { int len = pData?.Length ?? throw new ArgumentNullException(); return $"Die Datei ist {len} Bytes groß."; }
Hallo K. Pater,
ja wäre dann ja noch einfacher. Danke für den Hinweis. D.h. doch im Hintergrund wird dann vermutlich auch ein Thread erzeugt.
Gruß, Markus
-
Hi,
Frage mal beantwortet.
Nichtsdestotrotz muss man beim Debuggen was beachten, in der Entwicklungsumgebung was einstellen.
Wie gesagt, es kommt teils
Die Datei "f:\dd\NDP\fx\src\compmod\system\componentmodel\BackgroundWorker.cs" ist nicht vorhanden.
"f:\dd\NDP\fx\src\compmod\system\componentmodel\BackgroundWorker.cs" wird in Skriptdokumenten gesucht...Wenn ihr Zwei evtl. hier noch was sagen könntet. Ursache etc.
Gruß, Markus
-
wenn ich es richtig verstanden habe, handelt es sich im eine Disk-I/O-gebundene Aufgabe, die einen Task<int>liefert, der ThreadPool sollte dabei nicht in Anspruch genommen werden.
Hi K. Pater,
Quellserver-Unterstützung ist nicht angeklickt. Wie meinst das mit Threadpool? BackgroundWorker?
Gruß, Markus