2013-03-19 9 views
5

Comincio la mia forma nel solito modo:Qual è il modo corretto per chiudere a livello di codice un'applicazione WinForm dopo un certo periodo?

Application.Run(new MainForm()); 

voglio che aprire e gestire fino ad un certo periodo di tempo, quindi chiudere. Ho provato quanto segue ma inutilmente:

(1) Nel metodo Main (erano l'Application.Run() affermazione è), entro nella seguente DOPO Application.Run()

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

RISULTATO: Non viene mai colpito.

(2) PRIMA Application.Run() inizio un nuovo thread in background:

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

dove EndServiceThread è:

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

RISULTATO: vshost32.exe ha smesso di incidente di lavoro.

(3) In MainForm Tick evento:

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

RISULTATO: vshost32.exe ha smesso di incidente di lavoro.

Qual è il modo corretto per raggiungere il mio obiettivo? Ancora una volta, voglio avviare il modulo, averlo aperto & in esecuzione fino a una certa ora (Configs.EndService), quindi chiudere.

Grazie, Ben.

risposta

4

Creare un Timer e richiederne la chiusura nel gestore eventi.

Dire che si desidera che l'applicazione si spenga dopo 10 minuti. Si inizializza il timer con un periodo di 60.000 millisecondi. Il tuo gestore di eventi diventa:

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

Se si desidera chiudere a una data e ora specifica, si può avere la graduazione del timer una volta al secondo, e verificare DateTime.Now contro il tempo finale desiderato.

Ciò funzionerà perché il TimerTick verrà eseguito sul thread dell'interfaccia utente. Il problema con l'idea del thread separato era che Form.Close veniva chiamato su un thread in background, non il thread dell'interfaccia utente. Ciò genera un'eccezione. Quando interagisci con gli elementi dell'interfaccia utente, deve essere nel thread dell'interfaccia utente.

L'idea del thread in background probabilmente funzionerebbe se si chiamasse Form.Invoke per eseguire Close.

È inoltre possibile creare un oggetto WaitableTimer e impostarne l'evento per l'ora specifica. Il Framework non ha un WaitableTimer, ma uno è disponibile. Vedere l'articolo Waitable Timers in .NET with C#. Il codice è disponibile al numero http://www.mischel.com/pubs/waitabletimer.zip

Se si utilizza WaitableTimer, si consiglia di eseguire la richiamata su un thread in background.Dovrete Invoke sincronizzare con il thread UI:

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

Dove vuoi aggiungere questo? In 'MainForm', dal momento che questo è il punto di partenza del sistema per il resto dell'applicazione? –

+1

@Grant: Sì, posizionare il timer sul modulo principale. Imposta la sua proprietà 'Enabled' su' True', e il suo intervallo su qualsiasi intervallo di controllo temporale desiderato (1 secondo, 10 minuti, qualunque cosa). –

0

C'è evento "ServiceEnded"? Se sì, chiudi il modulo quando il servizio è terminato.

+0

Che ne dici di elaborare su come l'OP potrebbe fare questo? –

+0

il ragazzo che ha posto la domanda deve fornire un altro codice per ottenere una risposta migliore. Non penso che chiudere l'applicazione con il timer sia buono. – Dilshod

2

Che ne dite di qualcosa di simile:

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

Se si utilizza il System.Threading.Timer è possibile utilizzare il DueTime per impostare la prima volta che spara come il tempo che si desidera chiudere l'applicazione

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

Sei sicuro che è possibile chiamare 'Application.Exit' da un thread in background? Inoltre, ciò avrà esito negativo se l'orologio del sistema cambia (ad esempio, l'ora legale cambia) mentre il programma è in esecuzione. –

+0

Application.Exit sembra andare bene su un thread in background (l'ho provato prima di postare), il tempo di chiusura viene determinato quando viene creato il timer, quindi cambiare l'orologio non cambierà il tempo in cui il timer scatta –

+0

"Il tempo di chiusura viene determinato quando il tempo il timer è stato creato. " Non è affatto vero. La * quantità di tempo di attesa * è determinata al momento della creazione. Se avevi iniziato il programma a mezzanotte e volevi chiudere il programma alle 4:00, questo avrebbe atteso 4 ore. Ma il giorno della "primavera in anticipo", sarebbero le 5:00 del mattino prima che il timer scoppiasse. E il giorno del "ripiego", il timer segnava alle 3:00 del mattino. Se l'orologio di sistema cambia, qualsiasi intervallo di tempo basato sul valore precedente non è valido. –

Problemi correlati