结束用户控件中的计时器操作
本文关键字:计时器 操作 用户 控件 结束 | 更新日期: 2023-09-27 18:31:32
我在用户控件中结束计时器操作时遇到问题。我通过一些操作创建了用户控件,使用计时器间隔发生。我想实现这个目标:当用户使用我的用户控件关闭窗口时,操作(在 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
}
而InitializeComponent()
方法中的这一行TestUserControl.Control.Desinger.cs
:
this.ParentForm.FormClosing += new System.Windows.Forms.FormClosingEventHandler(ParentForm_FormClosing);
但是我在这一行中得到异常:类型为"System.NullReferenceException"的未处理异常
当前尝试的主要问题是,当从构造函数调用 InitializeComponent()
方法时,控件还没有Parent
值。这是异常告诉您的空值。
请参阅什么是 NullReferenceException 以及如何修复它?
解决此问题的最直接方法是首先删除所有Timer
初始化代码和Timer
字段,然后使用设计器将Timer
添加到UserControl
。然后,您甚至不必首先订阅父级的FormClosing
事件。
您可以在设计器的"工具箱"窗口中的"组件"类别下找到Timer
对象。您可以拖动或双击它以将其添加到UserControl
,就像任何其他工具箱项一样。它不会被放置在UserControl
本身上,而是放置在设计器自己的编辑窗口底部的区域供您UserControl
。您可以在那里选择它并设置Enabled
和Interval
等属性,以及为Tick
事件添加事件处理程序。
如果将其配置为将 Enabled
属性设置为 true
,则它将在创建UserControl
后立即启动。无论如何,通过以这种方式添加到UserControl
,它最终出现在控件自己的组件列表中,并在释放UserControl
本身时(即关闭父窗体时)自动释放(从而停止)。
请注意,正如"Idle_Mind"中的注释所指出的那样,由于Tick
处理程序是在 UI 线程上执行的,因此 UI 线程在运行时不会发生任何其他操作。这意味着(除其他事项外)如果Compute()
方法需要一些时间才能完成,则用户可能会察觉到从他们尝试关闭窗口到实际关闭窗口的延迟。
由于任何通常会发出关闭窗口信号的事件(例如鼠标单击、Alt+F4 等)在此期间甚至无法处理,因此确实没有好方法可以更改此行为(有一个不好的方法,我拒绝在这里描述)。在Compute()
方法完成之前,您甚至不会从用户那里收到该信号。
如果您需要能够在 Compute()
方法运行时通过用户输入中断该方法,那么一种选择是使用 System.Windows.Forms.Timer
以外的某个计时器,以便计时器处理程序将在单独的线程上运行,并使 UI 线程响应用户输入。另一种选择是将 Compute()
方法更改为异步方法,这样即使计时器事件本身是在 UI 线程上处理的,数据库操作也会异步处理,而不会阻塞 UI 线程。任何一个选项都是另一个问题,为了得到一个好的答案,需要有关您的Compute()
方法的特定详细信息,以显示您如何访问数据库和使用结果。:)