简体   繁体   English

在WinForm C#中使用System.Threading.Timer进行间隔的射击方法

[英]Firing method on interval with System.Threading.Timer in winForm C#

What I want to do is to use the System.Threading.Timer to execute a method with a interval. 我想要做的是使用System.Threading.Timer执行一个间隔的方法。 My example code looks like this atm. 我的示例代码看起来像这个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. 这个推测不是每10秒执行一次WriteSomething方法。 What rly happens is that the WriteSomething is executed when I run my application and after 10 seconds the application closes. 发生的事情是WriteSomething在我运行应用程序时执行,10秒后应用程序关闭。 Think I have missunderstood how this works, can anyone tell me how to do this with the System.Threading.Timer. 想想我已经误解了它是如何工作的,任何人都可以通过System.Threading.Timer告诉我如何做到这一点。

thanks in advance, code examples are very welcome 在此先感谢,代码示例非常受欢迎

The more likely scenario is that it crashes after 10 seconds. 更可能的情况是它在10秒后崩溃 You cannot touch any controls in the callback, it runs on the wrong thread. 您无法触及回调中的任何控件,它在错误的线程上运行。 You'd have to use Control.BeginInvoke(). 您必须使用Control.BeginInvoke()。 Which makes it utterly pointless to use a System.Threading.Timer instead of a System.Windows.Forms.Timer. 这使得使用System.Threading.Timer而不是System.Windows.Forms.Timer 完全没有意义

Be practical. 务实。 Make it 100 milliseconds so you don't grow a beard waiting for the crash. 让它达到100毫秒,这样你就不会长胡子等待崩溃。 And don't use an asynchronous timer to update the UI, it is useless. 并且不要使用异步计时器来更新UI,这是没用的。

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). 仅供参考,System.Windows.Forms计时器没有任何内容,它不允许您在代码中创建(它不仅仅是一个“拖放”计时器)。 Code: 码:

Constructor code: 构造函数代码:

  System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
  timer.Tick += OnTimerTick;
  timer.Interval = 10000;
  timer.Start();

Event Handler: 事件处理程序:

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

Just to reiterate what Hans said, in a WinForms application all GUI elements are not inherently thread-safe. 重申汉斯所说的,在WinForms应用程序中,所有GUI元素本身并不是线程安全的。 Almost all methods / properties on Control classes can only be called on the thread the GUI was created on. 几乎所有Control类的方法/属性都只能在创建GUI的线程上调用。 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). System.Threading.Timer在线程池线程上调用它的回调,而不是在你创建定时器的线程上调用它(参见下面的MSDN参考)。 As Hans said, you probably want a System.Windows.Forms.Timer instead, that will invoke your callback on the correct thread. 正如汉斯所说,你可能想要一个System.Windows.Forms.Timer,它将在正确的线程上调用你的回调。

You can always verify whether you can call methods on a Control (assuring you're on the correct thread) by using the code: 您始终可以使用以下代码验证是否可以调用Control上的方法(确保您使用正确的线程):

System.Diagnostics.Debug.Assert(!InvokeRequired); 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: 在您在构造函数中传递的回调方法上的System.Threading.Timer上的MSDN帮助中引用:

The method does not execute on the thread that created the timer; 该方法不会在创建计时器的线程上执行; it executes on a ThreadPool thread supplied by the system. 它在系统提供的ThreadPool线程上执行。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM