近期开发中常常遇到一个需求场景:在某个动做或事件执行完成后刷新、跳转页面或打开新页面。
该需求没有过多的业务逻辑,看起来也是比较容易实现,实际实现中也遇到了不大不小的毛病,在此总结一下。
什么是委托?
委托。即为A将接下来处理的代码委托B执行。
什么场景用委托?
一、多线程数据跨域。这其中包含:线程数据同步,页面实时刷新(即主线程等待子线程消息)或在某种特殊状况下用于建立子窗体。
二、实现winform未提供部分事件:例如主窗体下不一样分页实时切换,这也次本次记录的主要功能。
什么是异步?
一般程序需求流程能够理解为线性执行,能够列出时间轴。可是某些状况下须要程序同时执行A/B两个动做。程序同时执行多个动做,即为异步。
什么场景用异步?
跨线程操做。异步多用于刷新界面或切换页面。即在某个动做执行到必定进度后,在可视页面中实时通知用户,但执行该动做的线程没法跨域操做页面。
这时可使用委托,执行线程将通知界面线程执行刷新页面操做。
此处向下开始分解本次记录具体功能及实现过程
需求分析
需求:在查询完成后自动跳转结果页面。
很简单,最开始我觉得简单到不过是一行代码的事情。我已经打好了算盘。
分析程序:由于程序最开始设计并无该功能,并且为了实现首次需求中的简化分页,因此如今一个子界面中实际拥有三个子页面。且该子页面是在结果页面加载后被加载入主窗体中。因此至此能够得出如下结论:该页面(查询页面)不能直接操做主窗体。
因而决定才用委托事件,通知结果页面操做主窗体进行切换。
至此,基本分析结束。
构造委托事件
事件委由三个元素组成
一、委托事件(发通知页面)
二、委托对象(发通知页面)
三、执行事件(发通知页面)
四、提供回调事件(被通知页面)
四、绑定回调(被通知页面)
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); //绑定回调
此为第一次写的委托事件,而且放在手动结束中进行测试。运行成功。
以后继而移动到结束查询回调中执行,运行失败。错误为不可跨线程操做。
采用异步委托
既然错误信息为禁止跨线程操做,则能够采起的解决方案有:
一、建立新的线程,注入主窗体执行
二、使用异步委托
第一种方式天然不可取,由于该方案会致使原页面线程操做权被抢夺,会致使该次操做完成后页面中止响应。异步委托则是最优方案。
既然涉及到跨线程操做,那么咱们须要分析代码,肯定被跨越的线程,对将被通知的线程执行异步。
本次需求中,由查询线程通知页面线程,应当由页面线程执行刷新操做,因此应该判断页面线程是否被异步委托。
在执行事件中加入如下代码,此处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 }
至此,全部分析即实现结束。