silverlight 异步陷阱(一)不能Remove事件处理程序
2011-02-16 13:59
351 查看
Silverlight中许多操作都要去异步完成,但有时候会碰到多个异步操作需要按照一定顺序完成,事件是把异步操作转换成同步操作的一种方法。
lambda是操作事件的简洁方式,事件、lambda、同步组合在一起,就会产生事件处理程序不能移除的状况。看下面的代码:
代码public void LoadChapter(string uri)
{
//两个异步操作需要协调
EventHandler handler = (s, e) =>
{
if (this.PagedContentListView == null)
{
BookContentService contentService = new BookContentService();
EventHandler loadContentHandler = (ss, args) =>
{
//必须在外层执行完后执行
};
contentService.Loaded -= loadContentHandler;
contentService.Loaded += loadContentHandler;
contentService.Load(UriGenratorFaced.GeneratBookContentUri(uri));
}
Chapter = service.BookChapter;
};
service.Loaded -= handler;
service.Loaded += handler; }
两个事件处理程序嵌套,保证内层的loadContentHandler在外层handler执行后执行,使两个异步操作同步。
看代码逻辑应该能够正常运行,但是每执行一次LoadChapter方法,handler事件处理程序就会被注册一次,导致handler的执行次数加1。
问题的原因是由于内层嵌套的loadContentHandler ,导致service.Loaded -= handler,不能移除handler。
解决方法:问题找到了,解决方法可以有两种。
1、使事件处理程序只能注册一次
比如不使用lambda,在类的构造函数中执行事件处理程序。
使用lambda但是增加标记值,使事件只注册一次。
自定义事件注册方式等。
2、每次移除所有事件处理程序
参见:http://stackoverflow.com/questions/91778/how-to-remove-all-event-handlers-from-a-control
lambda是操作事件的简洁方式,事件、lambda、同步组合在一起,就会产生事件处理程序不能移除的状况。看下面的代码:
代码public void LoadChapter(string uri)
{
//两个异步操作需要协调
EventHandler handler = (s, e) =>
{
if (this.PagedContentListView == null)
{
BookContentService contentService = new BookContentService();
EventHandler loadContentHandler = (ss, args) =>
{
//必须在外层执行完后执行
};
contentService.Loaded -= loadContentHandler;
contentService.Loaded += loadContentHandler;
contentService.Load(UriGenratorFaced.GeneratBookContentUri(uri));
}
Chapter = service.BookChapter;
};
service.Loaded -= handler;
service.Loaded += handler; }
两个事件处理程序嵌套,保证内层的loadContentHandler在外层handler执行后执行,使两个异步操作同步。
看代码逻辑应该能够正常运行,但是每执行一次LoadChapter方法,handler事件处理程序就会被注册一次,导致handler的执行次数加1。
问题的原因是由于内层嵌套的loadContentHandler ,导致service.Loaded -= handler,不能移除handler。
解决方法:问题找到了,解决方法可以有两种。
1、使事件处理程序只能注册一次
比如不使用lambda,在类的构造函数中执行事件处理程序。
使用lambda但是增加标记值,使事件只注册一次。
自定义事件注册方式等。
2、每次移除所有事件处理程序
参见:http://stackoverflow.com/questions/91778/how-to-remove-all-event-handlers-from-a-control
相关文章推荐
- 小程序的事件处理参数不能取得
- 【C#】对异步请求处理程序IHttpAsyncHandler的理解和分享一个易用性封装 【手记】走近科学之为什么明明实现了IEnumerable<T>的类型却不能调用LINQ扩展方法 【手记】手机网页弹出层后屏蔽底层的滑动响应 【手记】ASP.NET提示“未能创建类型”处理 【Web】一个非常简单的移动web消息框 【手记】解决EXCEL跑SQL遇“查询无法运行或数据库表无法打开...”
- javascript事件处理------hml事件处理程序、dom0事件处理程序、dom2事件处理程序
- java例程练习(简单的画图程序[鼠标事件处理])
- 直接在HTML标记中指定事件处理程序
- 跨浏览器的事件处理程序
- c#给用户控件添加事件处理程序
- PetShop程序中的购物车和订单处理模块(Profile技术,异步MSMQ消息)
- Spring4.1新特性——异步调度和事件机制的异常处理
- 如何:创建同步/异步 HTTP 处理程序
- ASP.NET Google Maps Javascript API V3 实战基础篇一获取和设置事件处理程序中的属性
- 事件处理程序(HTML,DOM0,DOM2,IE)
- JavaScript高级程序设计学习笔记--事件(一)(事件流、事件处理程序/事件侦听器)
- JQ bind方法被选元素添加的一个或多个事件处理程序
- pulse_synchronizer(异步信号处理)程序理解
- 微信小程序 动态绑定数据及动态事件处理
- 使用jquery+一般处理程序异步加载信息
- javascript 事件处理程序介绍
- JS事件流与DOM事件处理程序
- JavaScript权威指南_168_第17章_事件处理_17.3-调用事件处理程序-返回值、调用顺序