2013-03-19 4 views
5

ich meine Form in der üblichen Art und Weise beginnen:Was ist der richtige Weg, eine WinForms-Anwendung nach einer bestimmten Zeit programmgesteuert zu schließen?

Application.Run(new MainForm()); 

ich es, bis eine bestimmte Zeit geöffnet werden soll und laufen, dann schließen. Ich habe das versucht, folgende, aber ohne Erfolg:

(1) in der Methode Main (waren die Application.Run() Aussage ist), habe ich folgendes eingeben NACH Application.Run()

while (DateTime.Now < Configs.EndService) { } 

Ergebnis: Es wird nie getroffen.

(2) VOR Application.Run() Ich beginne einen neuen Hintergrund-Thread:

 var thread = new Thread(() => EndServiceThread()) { IsBackground = true }; 
     thread.Start(); 

wo EndServiceThread ist:

public static void EndServiceThread() 
    { 
     while (DateTime.Now < Configs.EndService) { } 
     Environment.Exit(0); 
    } 

ERGEBNIS: vshost32.exe gestoppt hat Crash arbeiten.

(3) In Mainform Tick Veranstaltung:

 if (DateTime.Now > Configs.EndService) 
     { 
      this.Close(); 
      //Environment.Exit(0); 
     } 

ERGEBNIS: vshost32.exe hat Arbeits Absturz gestoppt.

Was ist der richtige Weg, um mein Ziel zu erreichen? Nochmals, ich möchte das Formular starten, lassen Sie es öffnen & läuft bis zu einer bestimmten Zeit (Configs.EndService), dann schließen.

Vielen Dank, Ben.

Antwort

4

Erstellen Sie eine Timer, und schließen Sie das Programm in seinem Event-Handler.

Angenommen, die Anwendung soll nach 10 Minuten heruntergefahren werden. Sie initialisieren den Timer mit einer Periode von 60.000 Millisekunden. Ihr Event-Handler wird:

void TimerTick(object sender) 
{ 
    this.Close(); 
} 

Wenn Sie es wollen, zu einem bestimmten Datum und Uhrzeit zu schließen, können Sie den Timer-Tick einmal pro Sekunde haben, und prüfen Sie DateTime.Now gegen die gewünschte Endzeit.

Dies funktioniert, weil die TimerTick auf dem UI-Thread ausgeführt wird. Das Problem mit Ihrer separaten Thread-Idee war, dass Form.Close in einem Hintergrundthread aufgerufen wurde, nicht der UI-Thread. Das löst eine Ausnahme aus. Wenn Sie mit UI-Elementen interagieren, muss dies im UI-Thread geschehen.

Ihre Hintergrund Thread-Idee würde wahrscheinlich funktionieren, wenn Sie Form.Invoke aufrufen, um die Close auszuführen. Sie können auch ein WaitableTimer Objekt erstellen und sein Ereignis für die bestimmte Zeit festlegen. Das Framework hat keine WaitableTimer, aber eine ist verfügbar. Siehe den Artikel Waitable Timers in .NET with C#. Code ist verfügbar unter http://www.mischel.com/pubs/waitabletimer.zip

Wenn Sie die WaitableTimer verwenden, beachten Sie, dass der Rückruf auf einem Hintergrundthread ausgeführt wird.Sie werden zu Invoke haben mit dem UI-Thread zu synchronisieren:

this.Invoke((MethodInvoker) delegate { this.Close(); }); 
+0

Wo schließen würdest du das hinzufügen? In 'MainForm', denn das ist der Startpunkt für den Rest der Anwendung? –

+1

@Grant: Ja, legen Sie den Timer auf das Hauptformular. Setzen Sie die Eigenschaft 'Enabled' auf 'True' und das Intervall auf das von Ihnen gewünschte Zeitintervall (1 Sekunde, 10 Minuten, was auch immer). –

0

Gibt es "ServiceEnded" Event? Wenn ja, schließen Sie Ihr Formular, wenn Ihr Service beendet wurde.

+0

Wie wäre es mit der Ausarbeitung, wie das OP dies tun könnte? –

+0

Der Typ, der die Frage gestellt hat, muss etwas mehr Code zur Verfügung stellen, um eine bessere Antwort zu erhalten. Ich denke nicht, dass das Schließen der Anwendung mit Timer gut ist. – Dilshod

2

Wie wäre es etwa so:

public partial class Form1 : Form 
{ 
    private static Timer _timer = new Timer(); 

    public Form1() 
    { 
     InitializeComponent(); 
     _timer.Tick += _timer_Tick; 
     _timer.Interval = 5000; // 5 seconds 
     _timer.Start();    
    } 

    void _timer_Tick(object sender, EventArgs e) 
    { 
     // Exit the App here .... 
     Application.Exit(); 
    } 
} 
0

Wenn Sie die System.Threading.Timer können Sie die DueTime verwenden das erste Mal setzen es als die Zeit feuert Sie Ihre Anwendung

new System.Threading.Timer((o) => Application.Exit(), null, (Configs.EndService - DateTime.Now), TimeSpan.FromSeconds(0)); 
Application.Run(new Form1()); 
+1

Sind Sie sicher, dass es sicher ist, 'Application.Exit' von einem Hintergrund-Thread aufzurufen? Außerdem wird dies fehlschlagen, wenn sich die Systemuhr während der Laufzeit ändert (zB Änderung der Sommerzeit). –

+0

Application.Exit scheint in einem Hintergrundthread in Ordnung zu sein (Ich habe dies vor dem Posten getestet). Die Schließzeit wird bestimmt, wenn der Timer erstellt wird. Das Ändern der Uhr ändert also nicht die Zeit, die der Timer auslöst –

+0

"Die Schließzeit wird bestimmt, wenn Timer wird erstellt. " Das ist überhaupt nicht wahr. Die * Wartezeit * wird zum Zeitpunkt der Erstellung festgelegt. Wenn Sie das Programm um Mitternacht gestartet haben und das Programm um 4:00 Uhr morgens schließen wollten, würde dies 4 Stunden warten. Aber am "Spring Ahead" -Tag wäre es 5:00 Uhr, bevor der Timer tickte. Und am Tag des "Rückfalls" würde der Timer um 3:00 Uhr ankreuzen. Wenn sich die Systemuhr ändert, ist jedes Zeitintervall, das auf dem vorherigen Wert basiert, ungültig. –

Verwandte Themen