在winformc#中使用System.Threading.Timer定时触发方法

本文关键字:定时 Timer 方法 Threading System winformc# | 更新日期: 2023-09-27 17:49:39

我想做的是使用System.Threading.Timer来执行一个间隔方法。我的示例代码看起来像这样:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        System.Threading.Timer t1 = new System.Threading.Timer(WriteSomething, null, TimeSpan.FromSeconds(0), TimeSpan.FromSeconds(10));
    }
    private void button1_Click(object sender, EventArgs e)
    {
        textBox1.Clear();
    }
    public void WriteSomething(object o)
    {
        textBox1.Text = "Test";
    }
}

}

这不是应该每10秒执行一次writessomething方法吗?真正发生的是,当我运行应用程序时执行writessomething,并在10秒后关闭应用程序。我想我误解了这是如何工作的,谁能告诉我如何用System.Threading.Timer来做到这一点。

提前感谢,代码示例非常欢迎

在winformc#中使用System.Threading.Timer定时触发方法

更可能的情况是在10秒后崩溃。你不能触摸回调中的任何控件,它在错误的线程上运行。你必须使用Control.BeginInvoke()。这使得完全没有意义使用System.Threading.Timer而不是System.Windows.Forms.Timer.

是实用。设置为100毫秒,这样你就不会在等待坠机时留胡子了。而且不要使用异步计时器来更新UI,这是没有用的。

供您参考,没有什么关于System.Windows.Forms的计时器不允许您在代码中创建(它不仅仅是一个"拖放"计时器)。代码:

构造函数代码:

  System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
  timer.Tick += OnTimerTick;
  timer.Interval = 10000;
  timer.Start();
事件处理程序:

  private void OnTimerTick(object sender, EventArgs e)
  {
    // Modify GUI here.
  }

重申Hans所说的,在WinForms应用程序中,并非所有GUI元素本质上都是线程安全的。几乎所有控件类上的方法/属性都只能在创建GUI的线程上调用。timer在线程池线程上调用它的回调,而不是在您创建计时器的线程上调用(参见下面来自MSDN的参考)。正如Hans所说,你可能需要一个System.Windows.Forms.Timer来代替,它会在正确的线程上调用你的回调。

你总是可以验证你是否可以调用控件上的方法(确保你在正确的线程上),使用以下代码:

System.Diagnostics.Debug.Assert (! InvokeRequired);

事件处理程序中的

。如果assert出错,则说明线程不能修改此控件。

在构造函数中传递回调方法时引用MSDN帮助中的System.Threading.Timer:

方法不执行创建计时器的线程;它在ThreadPool线程上执行由系统提供。

常见错误:需要将timer变量作为类成员,因为垃圾收集器可能会杀死它