我想要做的是使用System.Threading.Timer来执行带间隔的方法。 我的示例代码看起来像这个atm。
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";
}
}
}
这个suppost不是每隔10秒执行一次WriteSomething方法。发生的事情是WriteSomething在我运行应用程序时执行,10秒后应用程序关闭。以为我误解了它是如何工作的,任何人都可以通过System.Threading.Timer告诉我如何做到这一点。
提前感谢,非常欢迎代码示例
答案 0 :(得分:6)
更可能的情况是10秒后崩溃。您无法触及回调中的任何控件,它在错误的线程上运行。您必须使用Control.BeginInvoke()。这使得毫无意义使用System.Threading.Timer而不是System.Windows.Forms.Timer。
务实。让它达到100毫秒,这样你就不会长胡子等待崩溃。并且不使用异步计时器来更新UI,这是没用的。
答案 1 :(得分:4)
仅供参考,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.
}
答案 2 :(得分:2)
重申Hans所说的,在WinForms应用程序中,所有GUI元素本身并不是线程安全的。几乎所有Control类的方法/属性都只能在创建GUI的线程上调用。 System.Threading.Timer在线程池线程上调用它的回调,而不是在你创建定时器的线程上调用它(参见下面的MSDN参考)。正如汉斯所说,你可能想要一个System.Windows.Forms.Timer,它将在正确的线程上调用你的回调。
您始终可以使用以下代码验证是否可以在控件上调用方法(确保您使用正确的线程):
System.Diagnostics.Debug.Assert(InvokeRequired!);
在您的事件处理程序中。如果断言跳闸,则表示您处于无法修改此控件的线程上。
在System.Threading.Timer上的MSDN帮助中引用您在构造函数中传递的回调方法:
该方法不会执行 创建计时器的线程;它 在ThreadPool线程上执行 由系统提供。
答案 3 :(得分:0)
常见错误:需要将timer变量保留为类成员,因为垃圾收集器可能会将其杀死。