惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

aimingoo的专栏
aimingoo的专栏
Security Archives - TechRepublic
Security Archives - TechRepublic
NISL@THU
NISL@THU
T
The Exploit Database - CXSecurity.com
T
Threat Research - Cisco Blogs
A
Arctic Wolf
C
Cyber Attacks, Cyber Crime and Cyber Security
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
T
The Blog of Author Tim Ferriss
Simon Willison's Weblog
Simon Willison's Weblog
V
Visual Studio Blog
T
Tenable Blog
J
Java Code Geeks
C
CERT Recently Published Vulnerability Notes
The Register - Security
The Register - Security
The Cloudflare Blog
博客园 - 叶小钗
人人都是产品经理
人人都是产品经理
U
Unit 42
宝玉的分享
宝玉的分享
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 司徒正美
Last Week in AI
Last Week in AI
Forbes - Security
Forbes - Security
I
Intezer
云风的 BLOG
云风的 BLOG
雷峰网
雷峰网
Scott Helme
Scott Helme
月光博客
月光博客
Google Online Security Blog
Google Online Security Blog
T
Tailwind CSS Blog
爱范儿
爱范儿
Recent Commits to openclaw:main
Recent Commits to openclaw:main
L
LangChain Blog
S
Securelist
Spread Privacy
Spread Privacy
D
Darknet – Hacking Tools, Hacker News & Cyber Security
酷 壳 – CoolShell
酷 壳 – CoolShell
P
Proofpoint News Feed
C
Cybersecurity and Infrastructure Security Agency CISA
Hugging Face - Blog
Hugging Face - Blog
S
Security Affairs
S
SegmentFault 最新的问题
L
Lohrmann on Cybersecurity
Application and Cybersecurity Blog
Application and Cybersecurity Blog
T
Tor Project blog
博客园 - 聂微东
H
Heimdal Security Blog
B
Blog
Attack and Defense Labs
Attack and Defense Labs

博客园 - 张志敏

System.Net.Http for Silverlight 通过网页进行 iOS 应用内部分发 使用 Intel HAXM 为 Android 模拟器加速,媲美真机 Mono for Android 实现高效的导航 Activity 生命周期及其栈管理方式 我的第一个 Mono for Android 应用 谈谈 INotifyPropertyChanged 的实现 Task 编程中的异常处理 NHibernate 关系映射中的 Formula 开源一个 Sliverlight 导航框架 SQLite 常用 SQL 让 VS 编译 MonoTouch 项目源文件不再出错 MonoTouch绑定CocoaTouch类库 升级 Xcode 4.3 后找不到 xcodebuild 的解决方法 iOS 静态类库项目的建立与使用 从源代码编译里程碑的 ICS ROM IIS 7.5 下应用程序池的预定义账户 Web API 依赖注入与扩展 ASP.NET Web API 简介
在 Silverlight 5 项目中使用 async/await
张志敏 · 2012-07-21 · via 博客园 - 张志敏

.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 吧, 异步编程回归同步了!