2017-04-23 3 views
0

Ich habe eine Konsolenanwendung in Visual Studio 2008, C# und .NET Framework 3.5.Schließen Sie das Konsolenanwendungsfenster nach dem Drücken der Taste oder automatisch nach x Minuten

Wenn die Anwendung beendet, um alle Sachen zu tun, die ich Fenster schließen möchte, wenn Benutzer eine Taste drücken oder automatisch nach ein paar Minuten abgelaufen sind.

So am Ende meiner Anwendung, die ich tue:

static System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer(); 

public static int Main(string[] args) 
{ 
    // Do some stuff 
    Console.WriteLine("Press any key to close this window."); 

    myTimer.Tick += new EventHandler(TimerEventProcessor); 
    myTimer.Interval = 5000; 
    myTimer.Start(); 

    Console.ReadKey(); 

    return 0; 
} 


private static void TimerEventProcessor(Object myObject, EventArgs myEventArgs)  
{ 
    myTimer.Stop(); 
    Environment.Exit(0); 
} 

Das Problem hierbei ist, dass Fenster nach x Minuten nicht in der Nähe ist abgelaufen und auch Timer-Ereignis wird ausgelöst, nie da Programm für ein blockiertes wartet Schlüssel (Lesekey).

So wie es geht?

+0

Sie die falsche Art von Timer verwenden, können Sie nicht ein 'System.Windows.Forms.Timer' in einer Konsole App wie diese verwenden, benötigen Sie einen Timer, der nicht auf einem„UI-Thread angewiesen "Wie ein' System.Timers.Timer' –

Antwort

1

Versuchen Sie, die Arbeit zu bewegen, in einem separaten Thread durchgeführt werden:

public static int Main(...) 
{ 
    new System.Threading.Thread(Work).Start(); 
} 
private void Work() 
{ 
    // work to be done here 
} 

diese Weise kann die GUI-Thread Zeit zum Anheben des Timers tick Ereignis haben.

0

Ich habe eine mögliche Lösung gefunden, aber wenn die besten nicht sicher:

static System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer(); 

public static int Main(string[] args) 
{ 
    // Do some stuff 
    Console.WriteLine("Press any key to close this window."); 

    myTimer.Tick += new EventHandler(TimerEventProcessor); 
    myTimer.Interval = 5000; 
    myTimer.Start(); 

    // while (!Console.KeyAvailable) 
    //{ 
    //  Application.DoEvents(); 
    //  Thread.Sleep(250); 
    //} 

    // Above code replaced with: 
    Console.ReadKey(true); 

    DisposeTmr(); 

    return 0; 
} 

private static void DisposeTmr() 
{ 
    myTimer.Stop(); 
    myTimer.Dispose(); 
} 

private static void TimerEventProcessor(Object myObject, EventArgs myEventArgs)  
{ 
    DisposeTmr(); 
    Environment.Exit(0); 
} 

Problem mit dieser Lösung ist, dass diese Art von Timer synchron ist, und es ist notwendig, Application.DoEvents zu verwenden, wie here erläuterte. Außerdem bleibt der Timer im Status "Ausgesetzt", während der UI-Thread inaktiv ist. Dies kann dazu führen, dass der Timer-Event-Handler die Erfassung von Timer-Ereignissen nicht fortsetzt, während der Haupt-UI-Thread inaktiv ist.

Um dies zu vermeiden, gibt es zwei Optionen, System.Timers.Timer und System.Threading.Timer. Ich habe System.Threading.Timer Lösung wie unten umgesetzt und es funktioniert perfekt:

static System.Threading.Timer myTimer; 

public static int Main(string[] args) 
{ 
    // Do some stuff 
    Console.WriteLine("Press any key to close this window."); 

    myTimer = new System.Threading.Timer(TimerCallback, null, 5000, Timeout.Infinite); 

    while (!Console.KeyAvailable) 
    {   
     Thread.Sleep(250); 
    } 

    DisposeTmr(); 

    return 0; 
} 

private static void DisposeTmr() 
{ 
    if (myTimer != null) 
    { 
     myTimer.Dispose(); 
    } 
} 

private static void TimerCallback(Object myObject)  
{ 
    DisposeTmr(); 
    Environment.Exit(0); 
} 
1

Das Problem, das Sie haben, ist, dass Sie ein Formular Timer verwenden, die oben auf einem UI-Thread aufgehängt ist - für eine Konsole app . Sie beenden eine Umgebung nicht von der Konsole.

Wir müssen stattdessen den Threading-Timer verwenden. Aber das sollte nicht zu viel anders sein.

static Timer myTimer; 

    public static int Main(string[] args) 
    { 
     // Do some stuff 
     Console.WriteLine("Press any key to close this window."); 

     //Hey, I just met you and this is crazy 
     myTimer = new Timer(CallMeMaybe, null, 5000, 0); 

     //so call me maybe 
     Console.ReadKey(); 

     return 0; 
    } 

    //Instead of a tick, we have this 
    private static void CallMeMaybe(object state) 
    { 
     //But here's my number 
     Environment.Exit(0); 
    } 
Verwandte Themen