专栏首页张志敏的技术专栏在 Silverlight 5 项目中使用 async/await

在 Silverlight 5 项目中使用 async/await

在 Silverlight 5 项目中使用 async/await

.Net 4.5 提供了 async/await 让异步编程回归同步, 不过, async/await 不是只能在 .Net 4.5 下才能使用, 通过使用 Async Targeting Pack 就可以在 .Net 4.0 以及 Silverlight 5 项目中使用 async/await。

先来看一段 Silverlight 代码, 不使用 async/await 时是这样子的:

private void DistanceTestButtonClick(object sender, RoutedEventArgs routedEventArgs) {
	// 假设这是用户输入的坐标
	var point1 = GeometryUtil.CreateMapPointWgs84(113.3, 23.07);
	// 假设用户输入目的地坐标
	var point2 = GeometryUtil.CreateMapPointWgs84(110.3, 20);
	// 全局地图控件
	var map = App.ObjContainer.Resolve(typeof(Map));
	// 从当前 UI 上下文创建 TaskScheduler
	var uiContext = TaskScheduler.FromCurrentSynchronizationContext();
	// 创建三个几何服务
	var geoSvc1 = GeoFactory.CreateGeometryService();
	var geoSvc2 = GeoFactory.CreateGeometryService();
	var geoSvc3 = GeoFactory.CreateGeometryService();
	// 将用户输入的坐标投影为地图的坐标系坐标
	var task1 = geoSvc1.ProjectPointAsync(point1, map.SpatialReference);
	task1.ContinueWith(t1 => {
		point1 = task1.Result;
		// 目的地坐标投影为地图坐标
		var task2 = geoSvc2.ProjectPointAsync(point2, map.SpatialReference);
		task2.ContinueWith(t2 => {
			point2 = task2.Result;
			var buffParam = this.CreateBufferParameters(point2);
			var buffTask = geoSvc3.BufferTaskAsync(buffParam);
			// 做一次缓冲查询
			buffTask.ContinueWith(t3 => {
				var buffGeometry = buffTask.Result.First();
				var disParam = new DistanceParameters {
					DistanceUnit = LinearUnit.Meter,
					Geodesic = true
				};
				// 求距离
				var disTask1 = geoSvc1.DistanceTaskAsync(point1, point2, disParam);
				disTask1.ContinueWith(t4 => {
					var disTask2 = geoSvc2.DistanceTaskAsync(point1, buffGeometry.Geometry, disParam);
					disTask2.ContinueWith(t5 => {
						//最后求得最终距离
						var dis1 = disTask1.Result;
						var dis2 = disTask2.Result;
					}, uiContext);
				}, uiContext);
			}, uiContext);
		}, uiContext);
	}, uiContext);
}

看上面的代码, 做 Silverlight 开发的可真伤不起啊, Silverlight 阉割了所有的同步方法, 只能做异步查询, 本来是可以放在后台线程中模拟同步的,可偏偏 ArcGIS 提供的 Silverlight API 在回调函数中创建了 UI 元素以及 DepedencyObject , 想放到后台线程中计算也不行, 真是悲剧。

下面就请出 Async Targeting Pack 来拯救一下吧, 打开 NuGet 管理器, 输入 await 查询, 找到 Async Targeting Pack for Visual Studio 11 , 然后下载并添加引用到 Silverlight 项目, 开始用 async/await 改造上面的代码, 最终的结果如下, 看看是不是清爽了好多呢?

async private void DistanceTestButtonClick(object sender, RoutedEventArgs routedEventArgs) {
	 var point1 = GeometryUtil.CreateMapPointWgs84(113.3, 23.07);
	 var point2 = GeometryUtil.CreateMapPointWgs84(110.3, 20);
 
	 var map = App.ObjContainer.Resolve(typeof(Map));
 
	 var geoSvc1 = GeoFactory.CreateGeometryService();
	 var geoSvc2 = GeoFactory.CreateGeometryService();
	 var geoSvc3 = GeoFactory.CreateGeometryService();
 
	 point1 = await geoSvc1.ProjectGeometryAsync(point1, map.SpatialReference) as MapPoint;
	 point2 = await geoSvc2.ProjectGeometryAsync(point2, map.SpatialReference) as MapPoint;
 
	 var buffParam = this.CreateBufferParameters(point2);
	 var buffGeometry = (await geoSvc3.BufferTaskAsync(buffParam)).First();
 
	 var disParam = new DistanceParameters {
		  DistanceUnit = LinearUnit.Meter,
		  Geodesic = true
	 };
 
	 var dist1 = await geoSvc1.DistanceTaskAsync(point1, point2, disParam);
	 var dist2 = await geoSvc2.DistanceTaskAsync(point1, buffGeometry.Geometry, disParam);
 
	 var d = dist2 - dist1;
}

这样编译出来的 xap 包只是多了一个 dll, 依然可以在 Silverlight5 下运行, 客户端不需要安装任何软件。

大家赶快升级 VS2012 吧, 异步编程回归同步了!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • NHibernate 使用 SqlQuery

    多数情况下, NHibernate 提供的 HQL、 Linq 以及条件查询足够用了, 但是在某些情况下, 需要使用 SqlQuery, 使用 SqlQuery...

    beginor
  • 从 OAuth2 服务器获取授权授权

    搭建好了基于 OWIN 的 OAuth2 服务器之后, 接下来就是如何从服务器取得授权了, 下面就介绍如何实现 OAuth2 定义的四种授权方式。

    beginor
  • 使用 OWIN 作为 ASP.NET Web API 的宿主

    ASP.NET Web API 是一种框架,用于轻松构建可以访问多种客户端(包括浏览器和移动 设备)的 HTTP 服务。 ASP.NET Web API 是一种...

    beginor
  • ThingJS结合Web地图API开发,让数据展示更加出色!

    三维地图,是为了更好的数据可视化,以便更好地进行数据分析。ThingJS结合Web地图API开发了更多3D功能,让数据展示更加出色!

    森友鹿锘
  • 批量导出某个简书用户的所有文章列表和文章超链接

    虽然简书提供了批量下载文章的功能,但是下载到本地的文章都是markdown格式的,不包含文章的链接,这不满足我的需求。

    Jerry Wang
  • Arcgis for js实现北京地铁的展示

    在chrom中输入地址http://map.baidu.com/subways/index.html?c=beijing

    lzugis
  • 纯粹依靠位操作实现整数加法运算

    Jerry Wang
  • java10系列(二)Local-Variable Type Inference

    本文主要解读下java10的Local-Variable Type Inference

    codecraft
  • 基于 H5与WebGL 的科幻风机 3D 展示

      许多世纪以来,风力机同水力机械一样,作为动力源替代人力、畜力,对生产力的发展发挥过重要作用。近代机电动力的广泛应用以及二十世纪50年代中东油田的发现,使风机...

    HT for Web
  • 基于 HTML5 WebGL 的 3D 科幻风机

      许多世纪以来,风力机同水力机械一样,作为动力源替代人力、畜力,对生产力的发展发挥过重要作用。近代机电动力的广泛应用以及二十世纪50年代中东油田的发现,使风机...

    HT for Web

扫码关注云+社区

领取腾讯云代金券