2017-04-23 71 views
0

我在Visual Studio 2008,C#和.NET Framework 3.5中有一個控制檯應用程序。按下按鍵或在x分鐘後自動關閉控制檯應用程序窗口

當應用程序完成所有的事情時,我想關閉窗口,當用戶按下一個鍵或自動過了幾分鐘後。

因此,在我的應用程序結束時,我做的事:

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

這裏的問題是,窗口是不是X分鐘後關閉已經過去了,從來不會提得計時器事件,因爲程序被阻止等待鍵(ReadKey)。

那麼該怎麼做呢?

+0

您使用了錯誤類型的定時器,你不能在這樣一個控制檯應用程序使用'System.Windows.Forms.Timer',你需要不依賴於「UI線程計時器「像一個'System.Timers.Timer' –

回答

1

嘗試移動要做的工作到一個單獨的線程:

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

這樣的GUI線程都有時間,提高了定時器的Tick事件。

0

我找到了一個可能的解決方案,但如果沒有最好肯定:

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

問題與解決方案,這種類型的計時器是同步的,它是需要爲解釋here使用Application.DoEvents。此外,當UI線程正在休眠時,定時器仍處於暫停狀態,因此這可能導致定時器事件處理程序在主UI線程處於休眠狀態時不能繼續捕獲定時器事件。

爲了避免這種情況,有兩個選項:System.Timers.Timer和System.Threading.Timer。我已經實現如下System.Threading.Timer解決方案,它完美的作品:

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

你的問題是,您使用的是表計時,這是掛在一個UI線程 - 一個控制檯應用程序。您正在退出不是控制檯的環境。

我們需要使用線程計時器。但是,這應該沒有太大的不同。

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); 
    } 
相關問題