C# 如何在windows窗体中立即启动计时器?

C# 如何在windows窗体中立即启动计时器?,c#,winforms,visual-studio,C#,Winforms,Visual Studio,我有个小问题。这有点像国际象棋计时器。当我按下按钮时,当前计时器停止,第二次启动,但在1秒之后。如何立即启动第二个? 计时器确实会立即启动。问题是,您没有报告几秒钟,因此显示屏将显示0,直到一整秒钟过去,这在技术上是准确的 如果要立即显示1,只需以这种方式初始化变量即可 public Form1() { InitializeComponent(); sec1 = 1; sec2 = 1; } 计时器确实会立即启动。问题是,您没有报告几秒钟,因此显示屏将显示0,直到一整

我有个小问题。这有点像国际象棋计时器。当我按下按钮时,当前计时器停止,第二次启动,但在1秒之后。如何立即启动第二个?

计时器确实会立即启动。问题是,您没有报告几秒钟,因此显示屏将显示
0
,直到一整秒钟过去,这在技术上是准确的

如果要立即显示
1
,只需以这种方式初始化变量即可

public Form1() {
    InitializeComponent();
    sec1 = 1;
    sec2 = 1;
}
计时器确实会立即启动。问题是,您没有报告几秒钟,因此显示屏将显示
0
,直到一整秒钟过去,这在技术上是准确的

如果要立即显示
1
,只需以这种方式初始化变量即可

public Form1() {
    InitializeComponent();
    sec1 = 1;
    sec2 = 1;
}
编辑
我知道您的问题是“如何立即启动计时器”,但在您的代码中,计时器是立即启动的。当您调用start时,计时器启动。我相信您看到的效果与滴答声事件相关的延迟有关,根据我假设的描述,滴答声事件设置为1秒间隔。既然你说你正在尝试模拟类似于国际象棋计时器的东西(虽然在你的例子中是倒计时,而不是倒计时),那么使用类似秒表的东西,它可以启动、停止并显示经过的时间将是一个更接近的模型。因为有一个Stopwatch类正好提供了这种行为,所以我认为使用其中的两个类来实现它会更容易,并且只需要一个后台线程就可以根据需要频繁地更新UI。您甚至可以在每个按钮中添加一个更新调用,以确保文本框是最新的

===============================

也许您应该使用类的两个实例来代替计时器。这将不需要使用两个变量来跟踪秒数,因为Stopwatch类将保存每个计数器的运行时间

然后,在按钮方法中,您可以执行以下操作:

private Stopwatch sw1 = new Stopwatch();
private Stopwatch sw2 = new Stopwatch();

    private void button1_Click(object sender , EventArgs e) {
        sw1.Start();
        sw2.Stop();
    }
    private void button2_Click(object sender , EventArgs e) {
        sw2.Start();
        sw1.Stop();
    }
然后,您可以使用后台工作线程或其他后台线程来运行和更新文本框,其中包含计时器中经过的时间,您只需要获取经过的时间

// This will give you the total number of seconds elapsed.
var timer1Seconds = Math.Floor(sw1.Elapsed.TotalSeconds);
以下是如何将此更新设置为UI的示例:

    private bool _stop = false;
    public Form1()
    {
        InitializeComponent();

        Task.Run(() =>
        {
            while(!_stop)
            {
                UpdateElapsedTimes();
                Thread.Sleep(1000);
            }
        }
    }

    private void UpdateElapsedTimes()
    {
        if (InvokeRequired)
        {
            Invoke(UpdateElapsedTimes());
            return;
        }

        label1.Text = Math.Floor(sw1.Elapsed.TotalSeconds).ToString();
        label2.Text = Math.Floor(sw2.Elapsed.TotalSeconds).ToString();
    }
注意-在生产程序中,我不会使用布尔值作为循环检查器,您可以使用事件句柄,如果您想允许暂停更新,可能还需要使用两个事件句柄,这只是为了说明如何执行。您可以直接从thread方法调用并删除InvokeRequired检查,但为了额外的安全性,我添加了该检查,并且由于它在那里,所以我在循环中跳过了它。

Edit
我知道您的问题是“如何立即启动计时器”,但在您的代码中,计时器是立即启动的。当您调用start时,计时器启动。我相信您看到的效果与滴答声事件相关的延迟有关,根据我假设的描述,滴答声事件设置为1秒间隔。既然你说你正在尝试模拟类似于国际象棋计时器的东西(虽然在你的例子中是倒计时,而不是倒计时),那么使用类似秒表的东西,它可以启动、停止并显示经过的时间将是一个更接近的模型。因为有一个Stopwatch类正好提供了这种行为,所以我认为使用其中的两个类来实现它会更容易,并且只需要一个后台线程就可以根据需要频繁地更新UI。您甚至可以在每个按钮中添加一个更新调用,以确保文本框是最新的

===============================

也许您应该使用类的两个实例来代替计时器。这将不需要使用两个变量来跟踪秒数,因为Stopwatch类将保存每个计数器的运行时间

然后,在按钮方法中,您可以执行以下操作:

private Stopwatch sw1 = new Stopwatch();
private Stopwatch sw2 = new Stopwatch();

    private void button1_Click(object sender , EventArgs e) {
        sw1.Start();
        sw2.Stop();
    }
    private void button2_Click(object sender , EventArgs e) {
        sw2.Start();
        sw1.Stop();
    }
然后,您可以使用后台工作线程或其他后台线程来运行和更新文本框,其中包含计时器中经过的时间,您只需要获取经过的时间

// This will give you the total number of seconds elapsed.
var timer1Seconds = Math.Floor(sw1.Elapsed.TotalSeconds);
以下是如何将此更新设置为UI的示例:

    private bool _stop = false;
    public Form1()
    {
        InitializeComponent();

        Task.Run(() =>
        {
            while(!_stop)
            {
                UpdateElapsedTimes();
                Thread.Sleep(1000);
            }
        }
    }

    private void UpdateElapsedTimes()
    {
        if (InvokeRequired)
        {
            Invoke(UpdateElapsedTimes());
            return;
        }

        label1.Text = Math.Floor(sw1.Elapsed.TotalSeconds).ToString();
        label2.Text = Math.Floor(sw2.Elapsed.TotalSeconds).ToString();
    }

注意-在生产程序中,我不会使用布尔值作为循环检查器,您可以使用事件句柄,如果您想允许暂停更新,可能还需要使用两个事件句柄,这只是为了说明如何执行。您可以直接从thread方法调用并删除InvokeRequired检查,但为了额外的安全性,我添加了该检查,因为它在循环中存在,所以我跳过了它。

timer1和timer2在哪里声明?你的图像链接对我不起作用。我想我已经修复了它。我不知道你所说的“当前计时器停止,秒启动,但在1秒后”是什么意思。您的意思是当您单击第二个按钮时,第一个计时器正在停止,第二个计时器正在启动,但您希望它立即触发滴答事件,而不是等待您设置的计时器滴答时间?为什么使用字节?您正在寻找暂停方法。WinForm计时器没有。timer1和timer2在哪里声明?你的图像链接对我不起作用。我想我已经修复了它。我不知道你所说的“当前计时器停止,秒启动,但在1秒后”是什么意思。您的意思是当您单击第二个按钮时,第一个计时器正在停止,第二个计时器正在启动,但您希望它立即触发滴答事件,而不是等待您设置的计时器滴答时间?为什么使用字节?您正在寻找暂停方法。WinForm计时器没有。我不想显示1。就像国际象棋计时器一样。当您按下按钮时,当前计时器应停止并再次启动。但这是浪费1秒后pressing@MateGvenetadze-就像我上面的问题一样,你能澄清一下“浪费”是什么意思吗