2017-07-26 103 views
-2

我有一個簡單的C#程序(在MS中的Visual Studio 2010進行)。 它是一個帶有單個按鈕的窗體。正如你可以看到它只是一個簡單的程序,但我堅持它。 我想了解C#中的C#定時器和全局變量。計時器爲什麼不啓動?

我希望它按下按鈕時執行以下操作 出現一個消息框(每秒)顯示自按鈕被按下以來秒數 。 它應該通過設置變量starttimer爲真(在一個功能)工作,而在另一個函數時starttimer等於true檢測它示出了在消息框中秒的時間。

然而,這似乎並沒有檢測starttimer中其他功能等於true。所述startTimer所變量的目的是檢測按鈕按壓用於使用開始顯示該消息框每一秒。

那麼什麼來解決這個程序最簡單的方法?

PS當程序運行時沒有代碼starttimer它每秒都會顯示消息框(當程序啓動時)。

程序窗口形式的圖片顯示-as你可以看到它很簡單,只有一個按鈕。

namespace timerprogram 
{ 
    public partial class doeverysecond : Form 
    { 
     int thetimeinsecs = 0; 
     bool starttimer = false; 


     private void Form1_Load(object sender, EventArgs e) 
     { 

     }  

     private void customfn(object source, ElapsedEventArgs e) 
     { 
      if (starttimer == true) 
      { 
       thetimeinsecs = thetimeinsecs + 1; 
       MessageBox.Show(thetimeinsecs.ToString()); 
      } 
     } 

     public doeverysecond() 
     { 
      {    
       { 
        System.Timers.Timer mytimer = new System.Timers.Timer(); 
        mytimer.Elapsed += new ElapsedEventHandler(customfn); 
        mytimer.Interval = 1000; 
        mytimer.Start(); 
       } 
      } 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      starttimer = true; 
     } 
    } 
} 

enter image description here

+1

你永遠不會調用doeverysecond – Derek

+0

這是C#,而不是「C Sharp」 – Amy

+0

而且你不想每次都創建一個新的計時器,那麼「mytimer」應該移出課程。 – Derek

回答

0

定時器可能有點奇怪,但它看起來像你的主要問題是mytimer在方法範圍內,這意味着當該方法結束時,mytimer被垃圾回收器清理並且它停止運行。發生這種情況是因爲該方法結束後,無法從代碼中的其他地方再次訪問mytimer。爲了節省內存,.NET會在你清理完畢後,但在這種特殊情況下,知道你實際上仍然在使用計時器並不夠聰明。

解決方法很簡單,把mytimer放在課堂上。您也可以擺脫starttimerbool,因爲現在您可以檢查計時器本身以查看它是否正在運行。

你可以這樣做:

namespace timerprogram 
{ 
    public partial class doeverysecond : Form 
    { 
     //Timer is class level, so it sticks around and can be called from 
     //multiple methods 
     System.Timers.Timer mytimer = new System.Timers.Timer(); 
     int thetimeinsecs = 0; 

     private void Form1_Load(object sender, EventArgs e) 
     { 
      //Setup the timer, but don't start it 
      mytimer.Elapsed += new ElapsedEventHandler(customfn); 
      mytimer.Interval = 1000; 
     }  

     private void customfn(object source, ElapsedEventArgs e) 
     { 
      //We can check the timer itself to see if it's running! 
      if (mytimer.Enabled) 
      { 
       thetimeinsecs = thetimeinsecs + 1; 
       MessageBox.Show(thetimeinsecs.ToString()); 
      } 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      //Start the timer! 
      mytimer.Start(); 
     } 
    } 
} 

哦,至於是整個「範圍」的事情。在C#中,範圍基本上在{和a}之間。在方法和普通代碼中,在範圍內創建的變量不能被範圍外的代碼看到。這就是爲什麼你得到一個編譯錯誤,如果你這樣做:

if(something) 
{ 
    int x = 5; 
} 
x = x + 5; //x doesn't exist here! It disappears at } 

您可以訪問雖然範圍內的範圍之內的事情,所以

int x = 0; 
if(something) 
{ 
    x = 5; //x exists in an outside scope 
} 
x = x + 5; //This is fine 

凡是在班級範圍可略見一斑一個班級內的所有方法,這就是爲什麼計時器現在仍然存在。類範圍雖然略有不同,但是如果在其他類中公開之前可以看到其他類中的東西。方法也一樣(請注意,所有的方法都是'私人'的,所以外部的類不能調用它們,將它們改爲公共的,他們可以!)

+0

事實上,只要事件被註冊了。定時器將保留在內存中,直到敵人未註冊或程序結束。只要事件被註冊,垃圾收集器就不會觸摸計時器 –

+0

我沒有在原始程序中使用Form1_load。 Form1_load - 來自您的代碼 - 只要程序在屏幕上運行,它會自動調用 - 是嗎? Form1_load在窗體加載到屏幕/圖形內存時不會在開始時調用一次 –

-3

需要啓用定時器。

myTimer.Enabled = true 
+1

編號'開始()'將啓用計時器。 –

+1

OP在啓用計時器的構造函數中調用了'mytimer.Start();'。 –

2

那麼什麼來解決這個程序最簡單的方法?

實際上這將是按下按鈕,使得可變starttimer設置爲true,你將能看到MessageBox每一秒。你編程的作品!

除此之外,這將是很好的帶來更多的結構到你的程序,由具有通過單擊按鈕啓動定時器的方法:

private void button1_Click(object sender, EventArgs e) 
    { 
     if(!mytimer.Enabled) // this will prevent a double start 
     { 
      starttimer = true; 
      mytimer.Start(); 
     } 
    } 

構造應該擺脫定時啓動線:

public doeverysecond() 
{ 
    { 
     System.Timers.Timer mytimer = new System.Timers.Timer(); 
     mytimer.Elapsed += new ElapsedEventHandler(customfn); 
     mytimer.Interval = 1000; 
    } 
} 

責任分工在這裏很重要。構造函數用於初始化變量。所以這是他的工作。按鈕啓動計時器。

if-clause用於檢查if (starttimer == true)實際上並不是必需的,因爲您從不在代碼中的其他位置調用此方法。

並將布爾變量設置爲true 不是啓動計時器。這只是一面旗幟!

+0

實際上它會是按下按鈕,以便將變量啓動器設置爲true,並且您將能夠每秒鐘看到MessageBox。你編程的作品! 。 - 我還沒有得到它的工作 - 我一定是錯過了一些簡單的 –

+0

你的右起初可能有一個更好的名字 - 它的目的是在屏幕上顯示計時器 - 檢測按鈕的標誌按 –

+0

什麼版本的C犀利的使用? 2010? –