winForm C# 中使用 System.Threading.Timer 间隔触发方法
我想做的是使用 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";
}
}
这
不是假设每 10 秒执行一次 WriteSomething 方法吗?实际发生的情况是,当我运行应用程序时,会执行 WriteSomething,10 秒后应用程序将关闭。我想我误解了它是如何工作的,谁能告诉我如何使用 System.Threading.Timer 来做到这一点。
预先感谢,非常欢迎代码示例
What I want to do is to use the System.Threading.Timer to execute a method with a interval.
My example code looks like this 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";
}
}
}
Isn't this suppost to execute the WriteSomething method every 10'th second. What rly happens is that the WriteSomething is executed when I run my application and after 10 seconds the application closes. Think I have missunderstood how this works, can anyone tell me how to do this with the System.Threading.Timer.
thanks in advance, code examples are very welcome
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
更可能的情况是 10 秒后崩溃。您无法触摸回调中的任何控件,它在错误的线程上运行。您必须使用 Control.BeginInvoke()。这使得使用 System.Threading.Timer 而不是 System.Windows.Forms.Timer 完全没有意义。
务实一点。将其设置为 100 毫秒,这样您就不会在等待崩溃时长出胡须。并且不要使用异步定时器来更新UI,它是没有用的。
The more likely scenario is that it crashes after 10 seconds. You cannot touch any controls in the callback, it runs on the wrong thread. You'd have to use Control.BeginInvoke(). Which makes it utterly pointless to use a System.Threading.Timer instead of a System.Windows.Forms.Timer.
Be practical. Make it 100 milliseconds so you don't grow a beard waiting for the crash. And don't use an asynchronous timer to update the UI, it is useless.
仅供参考,System.Windows.Forms 计时器没有任何内容不允许您在代码中创建(它不仅仅是一个“拖放”计时器)。代码:
构造函数代码:
事件处理程序:
FYI, there is nothing about System.Windows.Forms timer that doesn't allow you to create in code (it's not just a "drag-and-drop" timer). Code:
Constructor code:
Event Handler:
只是重申 Hans 所说的,在 WinForms 应用程序中,所有 GUI 元素本质上都不是线程安全的。 Control 类上的几乎所有方法/属性只能在创建 GUI 的线程上调用。 System.Threading.Timer 在线程池线程上调用其回调,而不是在您创建计时器的线程上(请参阅下面来自 MSDN 的参考资料)。正如 Hans 所说,您可能需要一个 System.Windows.Forms.Timer,它将在正确的线程上调用您的回调。
您始终可以使用以下代码验证是否可以调用 Control 上的方法(确保您位于正确的线程上):
System.Diagnostics.Debug.Assert(!InvokeRequired);
在你的事件处理程序中。如果断言失败,则您所在的线程无法修改此控件。
引用自 MSDN 帮助 System.Threading.Timer 在您传递的回调方法上在构造函数中:
Just to reiterate what Hans said, in a WinForms application all GUI elements are not inherently thread-safe. Almost all methods / properties on Control classes can only be called on the thread the GUI was created on. The System.Threading.Timer invokes its callback on a thread pool thread, not the the thread you created the timer on (see reference below from MSDN). As Hans said, you probably want a System.Windows.Forms.Timer instead, that will invoke your callback on the correct thread.
You can always verify whether you can call methods on a Control (assuring you're on the correct thread) by using the code:
System.Diagnostics.Debug.Assert(!InvokeRequired);
inside your event handler. If the assert trips, you're on a thread that cannot modify this Control.
Quote from MSDN help on System.Threading.Timer on the callback method you passed in the constructor:
常见错误:需要将计时器变量保留为类成员,因为垃圾收集器可能会杀死它。
Common error: need to keep timer variable as class member as garbage collector may kill it.