通过定时器在给定时间装载UI,但是程序运行一定时间后,会报出Application.Run(new FrmMain());对象未实例化。
问题是随机地引发这个异常。
分析原因:
定时器启动后,程序变成多线程操作。而UI控件相对于不同的线程来说是共享资源,UI控件本身操作的时候不是线程安全的,也就是没有锁,会发生资源冲突。即访问 Windows 窗体控件本质上不是线程安全的。
而且这个错误无法使用try调试。
解决方法:
就是用Control.InvokeRequired去检查是否跨线程,然后用Invoke或BeginInvoke去更新控件。
在线程中,对UI的数据源进行的操作都使用委托。
委托是一种引用类型,表示对具有特定参数列表和返回类型的方法的引用。委托用于将方法作为参数传递给其他方法。
举例:
使用多线程更新DataGridView,防止页面卡顿和卡死的问题。
private delegate void UpdateDataGridView(List<StcokModel> sm, DataGridView dgv);
private void UpdateDgv(List<StcokModel> sm, DataGridView dgv)
{
if (dgv.InvokeRequired)
{
this.BeginInvoke(new UpdateDataGridView(UpdateDgv), new object[] { sm, dgv });
}
else
{
dgv.DataSource = sm;
dgv.Refresh();
}
}