2016-04-14 2 views
0

Ich habe hier ein bisschen ein Puzzler.Warum wird die Methode ohne Pause, aber mit Pause mit false zurückgegeben? C#

Hintergrund: Ich habe eine Anwendung, die Dateien protokolliert, die angezeigt wurden, nachdem ein Benutzer auswählt, welche Dateien angezeigt werden sollen.

Allerdings habe ich auch ein WinForm angezeigt, nachdem sie die Datei ausgewählt haben, die ausgeblendet bleibt, bis sie aus der Datei, die sie anzeigen, schließen. Hier

ist der entsprechende Code:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.IO; 
using System.Windows.Forms; 
using System.Diagnostics; 
using System.Threading; 

namespace ViewTracker 
{ 
    public partial class NewFile : Form 
    { 
     //checks to see if a file is open  
     public NewFile() 
     { 
      InitializeComponent(); 
      // 
      OpenDocuments(); 
      //starts the timer component 
      tm_CountDown.Start(); 


      while (CheckFileIsOpen() == false) 
      { 
       this.Hide(); 
      } 
      this.Show(); 
     } 

     //timer to count down 
     //executes every 1 second, interval of the timer component 
     private void tm_CountDown_Tick(object sender, EventArgs e) 
     { 
     } 
     #endregion 

     #region METHODS AND EVENTS 

     //opens documents based on file selection 
     private void OpenDocuments() 
     { 
     } 

     //SHUT DOWN EVERYTHING (files at least) 
     private void CloseEverything() 
     { 
     } 

     //checks to see if a file is open and when the file closes shows the new file select dialog 
     private bool CheckFileIsOpen() 
     { 
      Process[] pr_excel = Process.GetProcessesByName("EXCEL"); 
      Process[] pr_word = Process.GetProcessesByName("WINWORD"); 
      Process[] pr_pdf = Process.GetProcessesByName("ACROBAT"); 
      if (pr_excel.Count() != 0) 
      { 
       while (pr_excel[0].HasExited == false) 
       { 
        return false; 
       } 
      } 

      else if (pr_word.Count() != 0) 
      { 
       while (pr_word[0].HasExited == false) 
       { 
        return false; 
       } 
      } 

      else if (pr_pdf.Count() != 0) 
      { 
       while (pr_pdf[0].HasExited == false) ; 
       { 
        return false; 
       } 
      } 

      else if (prisonImages.Visible == true) 
      { 
       while (prisonImages.Visible == true) 
       { 
        return false; 
       } 
      } 

      return true; 
     } 
    } 
} 

Das Problem stellt sich bei while (CheckFileIsOpen() == false). Wenn ich eine Unterbrechung in Visual Studio in der Zeile einfüge und wenn dann durchführe, wird das Programm wie erwartet ausgeführt (das Formular bleibt ausgeblendet, bis die Prozesse nicht mehr vorhanden sind). Wenn ich jedoch ohne die Unterbrechung laufe, scheint es, als würde der Prozess nie ausgeführt.

Ich habe versucht, Thread.Sleep(1000) vor der while (CheckFileIsOpen() == false) Anweisung zu sehen, ob vielleicht nur den Thread für ein paar Sekunden zu stoppen gibt es eine Chance, den Prozess zu öffnen, aber dann friert die ganze Anwendung auf unbestimmte Zeit.

Die Fragen: Reagiert meine Anwendung nur zu schnell, um die Prozesse zu erfassen und zu feuern, bevor sie geöffnet werden? Und wenn ja, welche Optionen kann ich verwenden, um zu verhindern, dass es direkt zu der Annahme kommt, dass keine Prozesse offen sind?

Vielen Dank für Ihre Zeit.

EDIT:

landete ich eine Lösung, ein paar Minuten zu finden, nachdem dieses Posting. Ich änderte einige der Ausführungsschritte und verwendete schließlich die Methode Process.WaitForExit(), um meine Anforderungen zu erfüllen.

Falls sich jemand wundert, ist hier, wie CheckFileIsOpen() Werke jetzt:

private void CheckFileIsOpen() 
    { 
     Process[] pr_excel = Process.GetProcessesByName("EXCEL"); 
     Process[] pr_word = Process.GetProcessesByName("WINWORD"); 
     Process[] pr_pdf = Process.GetProcessesByName("ACROBAT"); 
     if (pr_excel.Count() != 0) 
     { 
      pr_excel[0].WaitForExit(); 
     } 

     else if (pr_word.Count() != 0) 
     { 
      pr_word[0].WaitForExit(); 
     } 

     else if (pr_pdf.Count() != 0) 
     { 
      pr_pdf[0].WaitForExit(); 
     } 
     } 
+1

Nur eine Ihrer "while" -Schleifen in 'CheckFileIsOpen()' kann mehr als einmal durchlaufen, und das ist die mit dem hinterhältigen kleinen ';' am Ende derselben Zeile. –

+0

Warum implementierst du das mit "busy wait" (while-loops)? Ein besserer Ansatz besteht darin, einen Timer zu verwenden und den Status gelegentlich zu überprüfen. –

+0

Anstatt Timer oder While-Schleifen zu verwenden, müssen Sie nur Ereignisse in Ihrem 'Form'-Objekt haben. Abonnieren Sie diese Ereignisse über die Eigentümeranwendung und reagieren Sie dann auf diese Ereignisse in ihren Handlern. https://msdn.microsoft.com/en-us/library/ms229603(v=vs.110).aspx (Siehe Abschnitt Ereignisgesteuerte Validierung) – Snoopy

Antwort

0

Mit Ihrer while-Schleife Ansatz Sie die gui Thead blockieren und Ihre Anwendung friert ein.

Rufen Sie in Ihrem Konstruktor this.Hide() auf und verwenden Sie einen anderen Zeitgeber. Rufen Sie im Timer-Tick-Ereignis Ihre Methode CheckFileIsOpen() auf, wenn dies einen falschen Aufruf this.Show() zurückgibt und stoppen Sie den Timer.