在Silverlight中的DispatcherTimer的Tick中使用基于事件的异步请求
需求:在silverlight用户界面上使用计时器定时刷新数据。
在 Silverlight 中的 DispatcherTimer 的 Tick 事件 中使用异步请求数据时,会出现多次请求的问题,以下是ViewModel的代码,看样子没什么问题:
using System;
using System.Net;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Threading; namespace AsyncTest.ViewModel
{
public class MainPageViewModel : NotificationBase
{
private int count;
public int Count
{
get
{
return count;
}
set
{
this.count = value;
base.OnPropertyChanged("Count");
}
} protected WcfService.Service1Client client = null;
private DispatcherTimer timer = null;
protected int Interval = ; public MainPageViewModel()
{
client = new WcfService.Service1Client();
timer = new DispatcherTimer();
timer.Interval = new System.TimeSpan(, , Interval);
timer.Tick += timer_Tick;
timer.Start();
}
private void timer_Tick(object sender, EventArgs ee)
{
client.GetDataAsync();
client.GetDataCompleted += ((s, e) => {
this.Count++;
});
}
}
}
然而,结果并不是我们预期的那样,每次请求成功后,Count会以这样的数列进行累加:1 3 6 10 15 21 。
经调试三天,排除在View层对ViewMode进行了多次初始化使Timer多次创建实例的可能,其他各种情况都排除后,最终把问题锁定在Tick的方法体。
后来又经过再三调试,终于知道特么的问题在哪了,卧槽我艹,允许我爆一句粗口,搞了两三天,妈蛋,才发现问题这么简单,仔细观察代码,可以看出这是基于事件的异步编程模型。
问题:在Tick的方法里,client.GetDataCompleted+=((s,e)=>{//do something}); ,那么每次到了Tick执行周期的时候都会"+=" 一次事件,所以给了我们多次请求的错觉,实际是请求了一次,只是多次执行了Completed事件而已。
这就是为什么Count的结果不是我们预期的 1 2 3 4 5 6 ... ,修改的代码如下:
private void timer_Tick(object sender, EventArgs ee)
{
client.GetDataAsync();
client.GetDataCompleted += client_GetDataCompleted;
} void client_GetDataCompleted(object sender, WcfService.GetDataCompletedEventArgs e)
{
//移除该事件,防止下次Tick事件执行时再次注册
client.GetDataCompleted -= client_GetDataCompleted;
this.Count++;
}
将Completed的事件单独提出来,在每次进入到Completed后,使用 "-=" 取消注册该事件,再次进入到Tick的时候,重新请求,重新绑定就OK了,也可以直接在ViewModel的构造函数里绑定Completed事件,每次Tick里只请求client.GetDataAsync(),不需要在进行+=client_GetDataCompleted ,两种方法皆可。
注意:实际项目中用到的是client_GetDataCompeleted事件的e.Result,这里是为了方便调试写的一个Demo,使用Count的目的是为了监测Compeleted到底执行了几次。
心得:每次遇到问题,不要急躁,可以由复杂到简单,若不知问题在哪可使用排除法将问题逐一排除,最后查找到问题所在,仔细分析,不断调试,找到问题根本,得到解决。
完!
在Silverlight中的DispatcherTimer的Tick中使用基于事件的异步请求的更多相关文章
- C#中的异步调用及异步设计模式(三)——基于事件的异步模式
四.基于事件的异步模式(设计层面) 基于事件的C#异步编程模式是比IAsyncResult模式更高级的一种异步编程模式,也被用在更多的场合.该异步模式具有以下优点: · ...
- C#中的异步调用及异步设计模式(二)——基于 IAsyncResult 的异步设计模式
三.基于 IAsyncResult 的异步设计模式(设计层面) IAsyncResult 异步设计模式通过名为 BeginOperationName 和 EndOperationName 的两个方法来 ...
- CAT中实现异步请求的调用链查看
CAT简介 CAT(Central Application Tracking),是美团点评基于 Java 开发的一套开源的分布式实时监控系统.美团点评基础架构部希望在基础存储.高性能通信.大规模在线访 ...
- wpf中应该使用c#四种定时器中的DispatcherTimer
c#中有四种定时器 1:System.Threading.Timer 使用: private System.Threading.Timer timerClose; timerClose = new S ...
- 地图四叉树一般用在GIS中,在游戏寻路中2D游戏中一般用2维数组就够了
地图四叉树一般用在GIS中,在游戏寻路中2D游戏中一般用2维数组就够了 四叉树对于区域查询,效率比较高. 原理图
- sqlserver 中数据导入到mysql中的方法以及注意事项
数据导入从sql server 到mysql (将数据以文本格式从sqlserver中导出,注意编码格式,再将文本文件导入mysql中): 1.若从slqserver中导出的表中不包含中文采用: bc ...
- 在Myeclipse中提交代码到GitHub中
这需要借助插件Egit,首先就是先下载该插件了,可以再eclipse中下载,也可以在外面下载,下载就不说了.下载地址git://github.com/houyongchao/plugin-Egit.g ...
- JQuery中使用Ajax实现诸如登录名检测等异步请求Demo
上一篇博客介绍了注册登录时一次性图形验证码的工具类的编写,这篇随笔同样是我在写用jquery中ajax实现登录信息检测的异步请求功能的笔记,在各个网站进行信息用户注册时,需要在不刷新页面的情况下对注册 ...
- AGS中通过FeatureServer插入数据失败、插入数据在WMTS请求中无法显示以及version概念的讨论
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.背景 在多个项目中,当我方接口给其他部门人员使用时出现了插入数据失 ...
随机推荐
- php下删除一篇文章生成的多个静态页面
php自定义函数之删除一篇文章生成的多个静态页面,可能有多页的文章,都是需要考虑到的. 复制代码代码如下: //– 删除一篇文章生成的多个静态页面 //– 生成的文章名为 5.html 5_2.ht ...
- 《WPF程序设计指南》读书笔记——第2章 基本画刷
1.Color结构 using System; using System.Windows; using System.Windows.Input; using System.Windows.Media ...
- main函数的正确格式
main函数称之为主函数,一个C程序总是从main()函数开始执行的.在关于C语言的网贴和图书中,可以看到main函数的多种格式,这些格式,有的是正确的,有的是不正确的,为了避免错误,现归纳整理如下. ...
- splObjectStroge的作用,实例化一个数组
PHP SPL SplObjectStorage是用来存储一组对象的,特别是当你需要唯一标识对象的时候. PHP SPL SplObjectStorage类实现了Countable,Iterator, ...
- mysqlsla慢查询分析工具教程
mysqlsla是一款帮助语句分析.过滤.和排序的功能,能够处理MySQL慢查询日志.二进制日志等.整体来说, 功能非常强大. 能制作SQL查询数据报表,分析包括执行频率, 数据量, 查询消耗等. 且 ...
- Python拷贝及多进程与类的问题
最近写python写的尤其不顺利,更多的debug,逐渐的深入,产出却比较少.应该是个瓶颈期,坚持坚持,厚着脸皮也要坚持下去. 0x00 拷贝问题 程序中涉及到多进程和协程,大致的模型是开了2+个进程 ...
- TOPAPI 消息通知机制
接收用户订阅消息 public class UserSubMain { public static void main(String[] args ) throws ApiException { St ...
- json tree
// 确定取消 ' return div; }, setCss: function () { var s = this.el.style; s.position = 'absolute'; s.top ...
- drag drop小游戏
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- 各个浏览器下实现Ajax的JS
var xmlhttpget; try { // Firefox, Opera 8.0+, Safari xmlhttpget = new window.XMLHttpRequest( ...