-2

我在 Windows 窗体应用程序中遇到了计时器问题。需要 Timer 记录归档时间的归档器。但是有什么东西打断了计时器?

我怀疑是溪流。关于什么可能导致计时器被中断的任何建议?

public partial class Form1 : Form
{
    int timerCounter = 0;
    System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();

    public Form1()
    {
        InitializeComponent();
        timer.Interval = 1000; 
        timer.Enabled = true;
    }

    public void button2_Click(object sender, EventArgs e)
    {
        timer.Start();
        timer.Tick += new EventHandler(timer1_Tick); 

        // code for archiving, streams

        timer.Stop(); 

        MessageBox.Show("Archive was created! :)");
    }

    public void timer1_Tick(object sender, EventArgs e)
    {
        this.label7.Text = (++timerCounter).ToString();
    }  

}

4

4 回答 4

7

Windows 窗体计时器不是多线程的。这意味着,tick 事件仅在程序空闲时触发(通过其消息队列接收消息)。在您的程序中,情况似乎并非如此。您可以轻松地检查这一点:如果您的 UI 在归档过程中是响应式的,那么Forms.Timer也会运行并且问题出在其他地方。如果它没有响应,那么表单(以及作为结果的计时器)将被阻塞(应用程序的消息队列中的任何消息都不会被处理)。

有两种方法可以解决这个问题:

  1. 要完成您想要实现的目标,您可以使用System.Timers.Timeror System.Threading.Timer,因为它们在后台异步运行。但是,UI 仍然不会更新(计时器方法将停止),因为 UI 仍然被阻止(见上文)。
  2. 另一种方法是使用后台工作程序进行归档过程(然后在另一个线程中运行)。UI 和计时器保持响应。
于 2012-11-29T11:17:35.953 回答
0

首先,您应该知道长时间运行的操作应该在 UI 线程之外的其他线程中执行。因此,您创建了一个处理线程,它自己进行归档,并使用 Control.Invoke 方法通知 UI。Control.Invoke 的 msdn 描述

于 2012-11-29T11:28:03.757 回答
-1

这里不需要使用计时器,为什么不直接使用TimeSpan

public void button2_Click(object sender, EventArgs e)
{
    DateTime startTime = DateTime.Now;

    // code for archiving, streams

    TimeSpan diff = DateTime.Now - startTime;

    MessageBox.Show("Archive was created! in " + diff.TotalSeconds + " seconds.");
}
于 2012-11-29T13:26:23.743 回答
-1

最初我认为您正在后台线程中执行存档。如果不是这样 - 您应该考虑使用 BackgroundWorker 在后台执行操作(这里有一些示例)。

不过,这是更简单的解决方案:

尝试添加Application.DoEvents()您的button2_Click处理程序(我猜您正在等待“流”完成归档)。要触发计时器和要让 label7 重绘其新文本值,应处理重绘事件。

于 2012-11-29T11:18:20.883 回答