C# 我的计时器赢了';t函数(我使用Visual Studio 2012)

C# 我的计时器赢了';t函数(我使用Visual Studio 2012),c#,winforms,timer,C#,Winforms,Timer,代码如下: System.Timers.Timer timer = new System.Timers.Timer(1000); 及 我对C#相当陌生,所以这可能是我犯的一个愚蠢的错误?当我按下空格键时。标签没有任何变化我认为您应该在启动计时器之前设置经过的事件委托 if (e.KeyCode == Keys.Space) { int count = 0; timer.Elapsed += delegate { cou

代码如下:

System.Timers.Timer timer = new System.Timers.Timer(1000);


我对C#相当陌生,所以这可能是我犯的一个愚蠢的错误?当我按下空格键时。标签没有任何变化

我认为您应该在启动计时器之前设置经过的事件委托

  if (e.KeyCode == Keys.Space)
  {
        int count = 0;
        timer.Elapsed += delegate
        {
          count++;
          ....
        }
        timer.Start();

 }

还包括if块内的代码,并将变量计数的声明移到委托代码外。将声明保留在事件代码中会在每次启动已运行事件时将其重置为零

我认为应该在启动计时器之前设置已运行事件委托

  if (e.KeyCode == Keys.Space)
  {
        int count = 0;
        timer.Elapsed += delegate
        {
          count++;
          ....
        }
        timer.Start();

 }

还包括if块内的代码,并将变量计数的声明移到委托代码外。将声明保留在事件代码中会在每次发生已过事件时将其重置为零

您需要将窗体的
KeyPreview
属性设置为
True
,以处理Windows窗体上的事件。

您需要将窗体的
KeyPreview
属性设置为
True
以处理窗体上的事件Windows窗体。

当计时器启动时,它将执行您的委托。看起来是这样的:

{
    int count = 0;
    count++;

    if (count == 1)
    {
       label1.Text = "3 (Get ready!)";
    }

    // cases for other values of count removed   

    timer.Stop();
}
private void mainWinForm_PreviewKeyDown_1(object sender, PreviewKeyDownEventArgs e)
{
    if (e.KeyCode == Keys.Space)
    {
        int count = 0; // NOTE: outside the delegate
        timer.Elapsed += delegate
        {
            count++;
            if (count == 1)
            {
                label1.Text = "3 (Get ready!)";
            }
            if (count == 2)
            {
                label1.Text = "2 (To smile! :) )";
            }
            if (count == 3)
            {
                label1.Text = "1 (Cheeese!)";
            }
            if (count == 4)
            {
                label1.Text = "Taken!";
                imgCapture.Image = imgVideo.Image;
                timer.Stop();
            }
        };
        timer.Start();
    }
}
private void mainWinForm_PreviewKeyDown_1(object sender, PreviewKeyDownEventArgs e)
{
    if (e.KeyCode == Keys.Space)
    {
        int count = 0; // NOTE: outside the delegate
        var timer = new System.Timers.Timer(1000);
        timer.Elapsed += delegate
        {
            count++;
            if (count == 1)
            {
                label1.Text = "3 (Get ready!)";
            }
            if (count == 2)
            {
                label1.Text = "2 (To smile! :) )";
            }
            if (count == 3)
            {
                label1.Text = "1 (Cheeese!)";
            }
            if (count == 4)
            {
                label1.Text = "Taken!";
                imgCapture.Image = imgVideo.Image;
                timer.Stop();
            }
        };
        timer.Start();
    }
}
现在,每次委托运行时,它都会创建一个新的局部变量并将其初始化为
0
。因此,您只能输入
count==1
分支。当委托完成时,它将禁用计时器。因此,您应该看到标签更改为
“3(准备好!)”
,然后再也不会发生任何事情。这就是代码所说的

您想要做的是,每次代理激发时都有不同的行为。您需要做的是让委托运行多次,并在每次运行时执行不同的操作。为了实现这一点,需要有一种机制,以便在代理的不同执行之间记住状态

你可以这样做:

  • count
    变量移到代理外部。它应该是表单类的私有字段。或者可能是向下键处理程序中的局部变量
  • 启动计时器前,将
    count
    初始化为
    0
  • 在代理中,增加计数,然后相应地设置标签文本
  • 如果检测到不需要对标签进行更多更新,请停止计时器
  • 您的代码可能如下所示:

    {
        int count = 0;
        count++;
    
        if (count == 1)
        {
           label1.Text = "3 (Get ready!)";
        }
    
        // cases for other values of count removed   
    
        timer.Stop();
    }
    
    private void mainWinForm_PreviewKeyDown_1(object sender, PreviewKeyDownEventArgs e)
    {
        if (e.KeyCode == Keys.Space)
        {
            int count = 0; // NOTE: outside the delegate
            timer.Elapsed += delegate
            {
                count++;
                if (count == 1)
                {
                    label1.Text = "3 (Get ready!)";
                }
                if (count == 2)
                {
                    label1.Text = "2 (To smile! :) )";
                }
                if (count == 3)
                {
                    label1.Text = "1 (Cheeese!)";
                }
                if (count == 4)
                {
                    label1.Text = "Taken!";
                    imgCapture.Image = imgVideo.Image;
                    timer.Stop();
                }
            };
            timer.Start();
        }
    }
    
    private void mainWinForm_PreviewKeyDown_1(object sender, PreviewKeyDownEventArgs e)
    {
        if (e.KeyCode == Keys.Space)
        {
            int count = 0; // NOTE: outside the delegate
            var timer = new System.Timers.Timer(1000);
            timer.Elapsed += delegate
            {
                count++;
                if (count == 1)
                {
                    label1.Text = "3 (Get ready!)";
                }
                if (count == 2)
                {
                    label1.Text = "2 (To smile! :) )";
                }
                if (count == 3)
                {
                    label1.Text = "1 (Cheeese!)";
                }
                if (count == 4)
                {
                    label1.Text = "Taken!";
                    imgCapture.Image = imgVideo.Image;
                    timer.Stop();
                }
            };
            timer.Start();
        }
    }
    
    这样做的一个问题是,看起来您将重新使用同一个计时器实例。因此,第二次订阅
    时,您将添加代理的第二个实例。我倾向于将计时器设为键关闭事件处理程序的局部变量

    那么代码将如下所示:

    {
        int count = 0;
        count++;
    
        if (count == 1)
        {
           label1.Text = "3 (Get ready!)";
        }
    
        // cases for other values of count removed   
    
        timer.Stop();
    }
    
    private void mainWinForm_PreviewKeyDown_1(object sender, PreviewKeyDownEventArgs e)
    {
        if (e.KeyCode == Keys.Space)
        {
            int count = 0; // NOTE: outside the delegate
            timer.Elapsed += delegate
            {
                count++;
                if (count == 1)
                {
                    label1.Text = "3 (Get ready!)";
                }
                if (count == 2)
                {
                    label1.Text = "2 (To smile! :) )";
                }
                if (count == 3)
                {
                    label1.Text = "1 (Cheeese!)";
                }
                if (count == 4)
                {
                    label1.Text = "Taken!";
                    imgCapture.Image = imgVideo.Image;
                    timer.Stop();
                }
            };
            timer.Start();
        }
    }
    
    private void mainWinForm_PreviewKeyDown_1(object sender, PreviewKeyDownEventArgs e)
    {
        if (e.KeyCode == Keys.Space)
        {
            int count = 0; // NOTE: outside the delegate
            var timer = new System.Timers.Timer(1000);
            timer.Elapsed += delegate
            {
                count++;
                if (count == 1)
                {
                    label1.Text = "3 (Get ready!)";
                }
                if (count == 2)
                {
                    label1.Text = "2 (To smile! :) )";
                }
                if (count == 3)
                {
                    label1.Text = "1 (Cheeese!)";
                }
                if (count == 4)
                {
                    label1.Text = "Taken!";
                    imgCapture.Image = imgVideo.Image;
                    timer.Stop();
                }
            };
            timer.Start();
        }
    }
    

    当计时器启动时,它将执行您的委托。看起来是这样的:

    {
        int count = 0;
        count++;
    
        if (count == 1)
        {
           label1.Text = "3 (Get ready!)";
        }
    
        // cases for other values of count removed   
    
        timer.Stop();
    }
    
    private void mainWinForm_PreviewKeyDown_1(object sender, PreviewKeyDownEventArgs e)
    {
        if (e.KeyCode == Keys.Space)
        {
            int count = 0; // NOTE: outside the delegate
            timer.Elapsed += delegate
            {
                count++;
                if (count == 1)
                {
                    label1.Text = "3 (Get ready!)";
                }
                if (count == 2)
                {
                    label1.Text = "2 (To smile! :) )";
                }
                if (count == 3)
                {
                    label1.Text = "1 (Cheeese!)";
                }
                if (count == 4)
                {
                    label1.Text = "Taken!";
                    imgCapture.Image = imgVideo.Image;
                    timer.Stop();
                }
            };
            timer.Start();
        }
    }
    
    private void mainWinForm_PreviewKeyDown_1(object sender, PreviewKeyDownEventArgs e)
    {
        if (e.KeyCode == Keys.Space)
        {
            int count = 0; // NOTE: outside the delegate
            var timer = new System.Timers.Timer(1000);
            timer.Elapsed += delegate
            {
                count++;
                if (count == 1)
                {
                    label1.Text = "3 (Get ready!)";
                }
                if (count == 2)
                {
                    label1.Text = "2 (To smile! :) )";
                }
                if (count == 3)
                {
                    label1.Text = "1 (Cheeese!)";
                }
                if (count == 4)
                {
                    label1.Text = "Taken!";
                    imgCapture.Image = imgVideo.Image;
                    timer.Stop();
                }
            };
            timer.Start();
        }
    }
    
    现在,每次委托运行时,它都会创建一个新的局部变量并将其初始化为
    0
    。因此,您只能输入
    count==1
    分支。当委托完成时,它将禁用计时器。因此,您应该看到标签更改为
    “3(准备好!)”
    ,然后再也不会发生任何事情。这就是代码所说的

    您想要做的是,每次代理激发时都有不同的行为。您需要做的是让委托运行多次,并在每次运行时执行不同的操作。为了实现这一点,需要有一种机制,以便在代理的不同执行之间记住状态

    你可以这样做:

  • count
    变量移到代理外部。它应该是表单类的私有字段。或者可能是向下键处理程序中的局部变量
  • 启动计时器前,将
    count
    初始化为
    0
  • 在代理中,增加计数,然后相应地设置标签文本
  • 如果检测到不需要对标签进行更多更新,请停止计时器
  • 您的代码可能如下所示:

    {
        int count = 0;
        count++;
    
        if (count == 1)
        {
           label1.Text = "3 (Get ready!)";
        }
    
        // cases for other values of count removed   
    
        timer.Stop();
    }
    
    private void mainWinForm_PreviewKeyDown_1(object sender, PreviewKeyDownEventArgs e)
    {
        if (e.KeyCode == Keys.Space)
        {
            int count = 0; // NOTE: outside the delegate
            timer.Elapsed += delegate
            {
                count++;
                if (count == 1)
                {
                    label1.Text = "3 (Get ready!)";
                }
                if (count == 2)
                {
                    label1.Text = "2 (To smile! :) )";
                }
                if (count == 3)
                {
                    label1.Text = "1 (Cheeese!)";
                }
                if (count == 4)
                {
                    label1.Text = "Taken!";
                    imgCapture.Image = imgVideo.Image;
                    timer.Stop();
                }
            };
            timer.Start();
        }
    }
    
    private void mainWinForm_PreviewKeyDown_1(object sender, PreviewKeyDownEventArgs e)
    {
        if (e.KeyCode == Keys.Space)
        {
            int count = 0; // NOTE: outside the delegate
            var timer = new System.Timers.Timer(1000);
            timer.Elapsed += delegate
            {
                count++;
                if (count == 1)
                {
                    label1.Text = "3 (Get ready!)";
                }
                if (count == 2)
                {
                    label1.Text = "2 (To smile! :) )";
                }
                if (count == 3)
                {
                    label1.Text = "1 (Cheeese!)";
                }
                if (count == 4)
                {
                    label1.Text = "Taken!";
                    imgCapture.Image = imgVideo.Image;
                    timer.Stop();
                }
            };
            timer.Start();
        }
    }
    
    这样做的一个问题是,看起来您将重新使用同一个计时器实例。因此,第二次订阅
    时,您将添加代理的第二个实例。我倾向于将计时器设为键关闭事件处理程序的局部变量

    那么代码将如下所示:

    {
        int count = 0;
        count++;
    
        if (count == 1)
        {
           label1.Text = "3 (Get ready!)";
        }
    
        // cases for other values of count removed   
    
        timer.Stop();
    }
    
    private void mainWinForm_PreviewKeyDown_1(object sender, PreviewKeyDownEventArgs e)
    {
        if (e.KeyCode == Keys.Space)
        {
            int count = 0; // NOTE: outside the delegate
            timer.Elapsed += delegate
            {
                count++;
                if (count == 1)
                {
                    label1.Text = "3 (Get ready!)";
                }
                if (count == 2)
                {
                    label1.Text = "2 (To smile! :) )";
                }
                if (count == 3)
                {
                    label1.Text = "1 (Cheeese!)";
                }
                if (count == 4)
                {
                    label1.Text = "Taken!";
                    imgCapture.Image = imgVideo.Image;
                    timer.Stop();
                }
            };
            timer.Start();
        }
    }
    
    private void mainWinForm_PreviewKeyDown_1(object sender, PreviewKeyDownEventArgs e)
    {
        if (e.KeyCode == Keys.Space)
        {
            int count = 0; // NOTE: outside the delegate
            var timer = new System.Timers.Timer(1000);
            timer.Elapsed += delegate
            {
                count++;
                if (count == 1)
                {
                    label1.Text = "3 (Get ready!)";
                }
                if (count == 2)
                {
                    label1.Text = "2 (To smile! :) )";
                }
                if (count == 3)
                {
                    label1.Text = "1 (Cheeese!)";
                }
                if (count == 4)
                {
                    label1.Text = "Taken!";
                    imgCapture.Image = imgVideo.Image;
                    timer.Stop();
                }
            };
            timer.Start();
        }
    }
    

    在我看来,您正在使用线程计时器。因此,将在不同的线程上调用经过的委托。不允许对UI进行交叉线程调用。您是否在调试器中禁用了异常?当您在经过的事件中将某些内容分配给label1.Text时,代码应该引发异常

    创建计时器后,将SynchronizingObject属性设置为属于UI线程的类(您的表单非常适合)。这将把经过的事件同步到主线程中,并且可以操纵UI

       var timer = new System.Timers.Timer(1000);
       timer.SynchronizingObject = this;
       timer.AutoReset = true; // the event will be fired just once no need to stop the timer. 
       timer.Elapsed += delegate
       {
          // your code
       }
    

    在我看来,您正在使用线程计时器。因此,将在不同的线程上调用经过的委托。不允许对UI进行交叉线程调用。您是否在调试器中禁用了异常?当您在经过的事件中将某些内容分配给label1.Text时,代码应该引发异常

    创建计时器后,将SynchronizingObject属性设置为属于UI线程的类(您的表单非常适合)。这将把经过的事件同步到主线程中,并且可以操纵UI

       var timer = new System.Timers.Timer(1000);
       timer.SynchronizingObject = this;
       timer.AutoReset = true; // the event will be fired just once no need to stop the timer. 
       timer.Elapsed += delegate
       {
          // your code
       }
    

    是否每次引发事件时都将count设置为0?因此,标签文本将始终为“3…”。当事件发生时,您正在停止计时器。您想做什么?您的代码将始终将文本设置为“准备就绪”,因为当计时器过期时,您将始终创建一个名为
    count
    的变量,其值为
    0
    。尝试将变量移到委托外部,使其保持不变。还要看一看(这种调试技术,它在大多数cas中非常有用