none
Datei innerhalb einer bestimmten Zeit einlesen, welche Möglichkeiten stehen zur Verfügung RRS feed

  • 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

    Donnerstag, 14. Dezember 2017 17:31

Antworten

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

    Donnerstag, 14. Dezember 2017 19:53
  • 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ß

    Freitag, 15. Dezember 2017 13:27
  • 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

    File

    Quelle
    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);
    }
        }


    Samstag, 16. Dezember 2017 13:05
  • 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ß


    Samstag, 16. Dezember 2017 13:43
  • 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

    Sonntag, 17. Dezember 2017 14:42
  • 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

    Montag, 18. Dezember 2017 17:46
  • Hallo Markus,

    Hast du unter Extras->Optionen->Debugging speziellere Optionen aktiviert (z.B. Quellserver-Unterstützung)?

    Gruß, K.

    Montag, 18. Dezember 2017 19:29
  • Hallo 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.

    Gruß

    Montag, 18. Dezember 2017 19:30
  • 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

    Dienstag, 19. Dezember 2017 17:36