委托事件+异步执行
2017-07-05 14:46
232 查看
近期开发中经常遇到一个需求场景:在某个动作或事件执行完成后刷新、跳转页面或打开新页面。
该需求没有过多的业务逻辑,看起来也是比较容易实现,实际实现中也遇到了不大不小的毛病,在此总结一下。
什么是委托?
委托。即为A将接下来处理的代码委托B执行。
什么场景用委托?
1、多线程数据跨域。这其中包含:线程数据同步,页面实时刷新(即主线程等待子线程消息)或在某种特殊情况下用于创建子窗体。
2、实现winform未提供部分事件:例如主窗体下不同分页实时切换,这也次本次记录的主要功能。
什么是异步?
通常程序需求流程可以理解为线性执行,可以列出时间轴。但是某些情况下需要程序同时执行A/B两个动作。程序同时执行多个动作,即为异步。
什么场景用异步?
跨线程操作。异步多用于刷新界面或切换页面。即在某个动作执行到一定进度后,在可视页面中实时通知用户,但执行该动作的线程无法跨域操作页面。
这时可以使用委托,执行线程将通知界面线程执行刷新页面操作。
此处向下开始分解本次记录具体功能及实现过程
需求分析
需求:在查询完成后自动跳转结果页面。
很简单,最开始我以为简单到不过是一行代码的事情。我已经打好了算盘。
分析程序:因为程序最开始设计并没有该功能,而且为了实现首次需求中的简化分页,所以现在一个子界面中实际拥有三个子页面。且该子页面是在结果页面加载后被加载入主窗体中。所以至此可以得出以下结论:该页面(查询页面)不能直接操作主窗体。
于是决定才用委托事件,通知结果页面操作主窗体进行切换。
至此,基本分析结束。
构造委托事件
事件委由三个元素组成
1、委托事件(发通知页面)
2、委托对象(发通知页面)
3、执行事件(发通知页面)
4、提供回调事件(被通知页面)
4、绑定回调(被通知页面)
此为第一次写的委托事件,并且放在手动结束中进行测试。运行成功。
之后继而移动到结束查询回调中执行,运行失败。错误为不可跨线程操作。
采用异步委托
既然错误信息为禁止跨线程操作,则可以采取的解决方案有:
1、创建新的线程,注入主窗体执行
2、使用异步委托
第一种方式自然不可取,因为该方案会导致原页面线程操作权被抢夺,会导致该次操作完成后页面停止响应。异步委托则是最优方案。
既然涉及到跨线程操作,那么我们需要分析代码,确定被跨越的线程,对将被通知的线程执行异步。
本次需求中,由查询线程通知页面线程,应当由页面线程执行刷新操作,所以应该判断页面线程是否被异步委托。
在执行事件中加入以下代码,此处this指刷新的页面
至此,所有分析即实现结束。
该需求没有过多的业务逻辑,看起来也是比较容易实现,实际实现中也遇到了不大不小的毛病,在此总结一下。
什么是委托?
委托。即为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 }
至此,所有分析即实现结束。
相关文章推荐
- C#固定时间执行指定事件(观察者模式+异步委托)
- C#固定时间执行指定事件(观察者模式+异步委托)
- jquery异步调用自数据库获取值通过knockoutjs赋值给职位二级菜单导致的jquery的hover事件不执行的例子
- 经典Demo(委托、事件、多线程、异步)
- 多播委托如何异步并发执行
- 委托-异步调用-泛型委托-匿名方法-Lambda表达式-事件【转】
- Spring中使用@Async注解使Even监听事件之间的执行变为异步
- boost asio的异步事件处理函数是在执行异步事件的run函数所在的线程里面执行的
- NET中级课--浅谈委托,事件,异步调用,回调等概念
- 委托的同步执行和异步执行(例子)
- js---JavaScript中的事件委托/事件代理,如何通过事件委托进行异步DOM事件监听
- 事件、委托、异步同步
- 转载NET体系下的回调与异步调用之委托与事件机制
- 多个按钮执行相同事件(委托)
- C#例子 易懂故事 接口 委托 事件 异步通知 好玩.
- asp.net开发-记录-委托不执行(EventHandler事件无反应)
- PHP 命令行模式实战之cli+mysql 模拟队列批量发送邮件(在Linux环境下PHP 异步执行脚本发送事件通知消息实际案例)
- C# 委托事件的异步调用
- JQuery写的公用遮罩层+关闭遮罩层时执行委托事件
- js 异步和事件的执行问题