在用户控件中结束计时器操作

时间:2014-11-23 17:28:03

标签: c# winforms .net-3.5

我在用户控制中结束计时器操作存在问题。我通过一些操作创建了用户控件,使用Timer以间隔发生。我想实现这个目标: 当用户使用我的用户控件关闭窗口时,操作(在Calculate()方法中)停止。这是我在MyUserControl.cs中的代码:

   // fields
   private Timer timer; 

    // ctor
    public TestUserControl()
    {
       InitializeComponent();
       timer = new Timer();   
       timer.Tick += timer_Tick;
       timer.Interval = 5000;
       timer.Start();
    }

    void timer_Tick(object sender, EventArgs e)
    {
        Compute();
    }

    void ParentForm_FormClosing(object sender, FormClosingEventArgs e)
    {
        timer.Stop();
    }

    private static void Compute()
    {
       // do something
    }

TestUserControl.Control.Desinger.cs方法中InitializeComponent()中的这一行:

this.ParentForm.FormClosing += new System.Windows.Forms.FormClosingEventHandler(ParentForm_FormClosing);

但是我在这一行中遇到异常:类型' System.NullReferenceException'

的未处理异常

1 个答案:

答案 0 :(得分:0)

当前尝试的主要问题是,当从构造函数调用InitializeComponent()方法时,控件还没有Parent值。这是异常告诉你的空值。

请参阅What is a NullReferenceException and how do I fix it?

解决此问题的最直接方法是首先删除所有Timer初始化代码和Timer字段,然后使用Designer添加{{1}到你的Timer。那么你甚至不必首先订阅父亲的UserControl事件。

您可以在Designer的“工具箱”窗口的“组件”类别下找到FormClosing对象。您可以拖动或双击它,将其添加到Timer,就像任何其他工具箱项一样。它不会被放置在UserControl本身上,而是放置在Designer UserControl的编辑窗口底部的区域中。您可以在那里选择它并设置UserControlEnabled等属性,并为Interval事件添加事件处理程序。

如果将其配置为Tick属性设置为Enabled,则会在创建true后立即启动。无论如何,通过以这种方式添加到UserControl,它会在控件自己的组件列表中结束,并且当UserControl本身被释放时,即当父项被释放时将自动处理(并因此停止)表格已关闭。

请注意,正如“Idle_Mind”中的注释所指出的那样,因为您的UserControl处理程序在UI线程上执行,所以UI线程在运行时不会发生任何其他事情。这意味着(除其他事项外)如果Tick方法需要一些时间才能完成,用户可能会感觉到他们尝试关闭窗口时以及实际关闭时的延迟。

由于任何事件(例如鼠标点击, Alt + F4 等)通常会发出关闭窗口的信号,因此在此期间甚至无法处理真的没有什么好方法可以改变这种行为(这是一种糟糕的方式,我在这里拒绝描述)。在Compute()方法完成之前,您甚至不会收到用户发出的信号。

如果你需要能够在运行时通过用户输入中断Compute()方法,那么一个选项是使用Compute()以外的某个计时器,这样定时器处理程序就会运行一个单独的线程,让UI线程响应用户输入。另一种选择是将System.Windows.Forms.Timer方法更改为异步方法,以便即使在UI线程上处理计时器事件本身,也可以异步处理数据库操作,而不会阻止UI线程。这两个选项都是另一个问题,如果有一个好的答案,则需要有关Compute()方法的具体详细信息,说明您如何访问数据库并使用结果。 :)