0

好的,我有这个timer控件,当我启动程序时它运行良好,但是当我最大化或最小化表单时,计时器控件停止工作。什么都不更新?这是代码

public MainForm()
        {
            InitializeComponent();
            var tm =
                new System.Threading.Timer(state => statusDateTimeLabel.Text = DateTime.Now.ToLocalTime().ToString(CultureInfo.InvariantCulture), null, TimeSpan.FromMilliseconds(0),
                TimeSpan.FromMilliseconds(1000));                
        }

有时,标签甚至不更新,有时它会更新。但主要问题是,当我最大化表单时,再次恢复它时,它会停止更新时间。谁能解释我做错了什么?

如果不清楚,我在状态栏中有这个标签控件,我想在该标签中显示当前日期时间。

认为这可能是因为这个线程可能正忙于做其他事情,我什至尝试了这个

public MainForm()
    {
        InitializeComponent();
        ThreadPool.QueueUserWorkItem(delegate(object state)
                                         {
                                             new System.Threading.Timer(
                                                 stateObj =>
                                                 statusDateTimeLabel.Text =
                                                 DateTime.Now.ToLocalTime().ToString(CultureInfo.InvariantCulture),
                                                 null, TimeSpan.FromMilliseconds(0),
                                                 TimeSpan.FromMilliseconds(1000));
                                         });
    }

但是这又和上面一样,有时它会更新,有时它不会,让我感到困惑的是,当我最大化表单甚至调整它的大小时,它会停止更新?任何人都可以帮我找出问题所在吗?

4

3 回答 3

3

更新文本的回调未在 UI 线程上执行。尝试以下操作:

var context = SynchronizationContext.Current;
var tm = new System.Threading.Timer(state => 
{
  context.Send(delegate() { statusDateTimeLabel.Text = DateTime.Now.ToLocalTime().ToString(CultureInfo.InvariantCulture); });
}, null, TimeSpan.FromMilliseconds(0), TimeSpan.FromMilliseconds(1000));
于 2012-10-16T10:07:24.010 回答
2

您没有保持对它的引用,因此在某个时间点,它将被垃圾收集。见Timer

只要您使用Timer,就必须保留对它的引用。与任何托管对象一样,当没有对Timer的引用时,它会受到垃圾回收的影响。Timer仍然处于活动状态的事实并不能阻止它被收集。

并做:

Timer tm; //Moved to a field

public MainForm()
        {
            InitializeComponent();
            tm =
                new System.Threading.Timer(state => statusDateTimeLabel.Text = DateTime.Now.ToLocalTime().ToString(CultureInfo.InvariantCulture), null, TimeSpan.FromMilliseconds(0),
                TimeSpan.FromMilliseconds(1000));                
        }

(虽然,正如其他人指出的那样,如果您在计时器回调中所做的工作是与 UI 交互,那么您可能选择了错误的组件)

于 2012-10-16T10:08:49.473 回答
0

如果您使用的是 Windows 窗体,则应使用 System.Windows.Forms.Timer 而不是 System.Threading.Timer,如下所示:http: //msdn.microsoft.com/en-us/library/system.threading.timer.aspx

于 2012-10-18T15:12:23.147 回答