委托事件+异步执行

近期开发中经常遇到一个需求场景:在某个动作或事件执行完成后刷新、跳转页面或打开新页面。
该需求没有过多的业务逻辑,看起来也是比较容易实现,实际实现中也遇到了不大不小的毛病,在此总结一下。
 
什么是委托?

委托。即为A将接下来处理的代码委托B执行。
 
什么场景用委托?

1、多线程数据跨域。这其中包含:线程数据同步,页面实时刷新(即主线程等待子线程消息)或在某种特殊情况下用于创建子窗体。
2、实现winform未提供部分事件:例如主窗体下不同分页实时切换,这也次本次记录的主要功能。
 
什么是异步?

通常程序需求流程可以理解为线性执行,可以列出时间轴。但是某些情况下需要程序同时执行A/B两个动作。程序同时执行多个动作,即为异步。
 
什么场景用异步?

跨线程操作。异步多用于刷新界面或切换页面。即在某个动作执行到一定进度后,在可视页面中实时通知用户,但执行该动作的线程无法跨域操作页面。
这时可以使用委托,执行线程将通知界面线程执行刷新页面操作。
 
 
此处向下开始分解本次记录具体功能及实现过程
 
需求分析

需求:在查询完成后自动跳转结果页面。
很简单,最开始我以为简单到不过是一行代码的事情。我已经打好了算盘。
分析程序:因为程序最开始设计并没有该功能,而且为了实现首次需求中的简化分页,所以现在一个子界面中实际拥有三个子页面。且该子页面是在结果页面加载后被加载入主窗体中。所以至此可以得出以下结论:该页面(查询页面)不能直接操作主窗体。
于是决定才用委托事件,通知结果页面操作主窗体进行切换。
至此,基本分析结束。
 
构造委托事件

事件委由三个元素组成
1、委托事件(发通知页面)
2、委托对象(发通知页面)
3、执行事件(发通知页面)
4、提供回调事件(被通知页面)
4、绑定回调(被通知页面)
1 public delegate void DeleDialogExend(); //委托事件
2 public event DeleDialogExend EventDialogExend; //委托对象
3 public void DialogExend() //执行事件
4 { /**跳转代码**/ }
5 public void DialogExend() //回调事件
6 { /**执行代码**/ }
7 page.EventDialogExend += new ToolByExtendWord.DeleDialogExend(DialogExend); //绑定回调
 
此为第一次写的委托事件,并且放在手动结束中进行测试。运行成功。
之后继而移动到结束查询回调中执行,运行失败。错误为不可跨线程操作。
 
 
采用异步委托

既然错误信息为禁止跨线程操作,则可以采取的解决方案有:
1、创建新的线程,注入主窗体执行
2、使用异步委托
第一种方式自然不可取,因为该方案会导致原页面线程操作权被抢夺,会导致该次操作完成后页面停止响应。异步委托则是最优方案。
 
既然涉及到跨线程操作,那么我们需要分析代码,确定被跨越的线程,对将被通知的线程执行异步。
本次需求中,由查询线程通知页面线程,应当由页面线程执行刷新操作,所以应该判断页面线程是否被异步委托。
在执行事件中加入以下代码,此处this指刷新的页面
1 public void DialogExend()
2 {
3 if (EventDialogExend != null)
4 {
5 if (this.InvokeRequired) this.Invoke(new DeleDialogExend(DialogExend));
6 else EventDialogExend();
7 }
8 }
至此,所有分析即实现结束。
 
 
 
原文地址:https://www.cnblogs.com/Z-onee/p/7121288.html