2017-07-26 84 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? –