我在用户控制中结束计时器操作存在问题。我通过一些操作创建了用户控件,使用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'
的未处理异常答案 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
的编辑窗口底部的区域中。您可以在那里选择它并设置UserControl
和Enabled
等属性,并为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()
方法的具体详细信息,说明您如何访问数据库并使用结果。 :)